Sida 1 av 1
Modulo och python
Postat: 12 dec 2007, 03:57
av Niklas Bolmdahl
Eller, ja ... matte och python antar jag att det borde stå egentligen.
Håller på o leker lite med Python (som det heter när en idiot sitter med en bok o försöker prata franska)
och jag fattar verkligen inte hur Python "tänker". Eller, jo, men inte varför.
Om jag startar den interaktiva prompten och skriver följande:
Kod: Markera allt
>>>4/(-3)
-2
>>>4%(-3)
-2
>>>4/3
1
>>>4%3
1
... så blir jag inte riktigt glad.
Samma resultat blir det av
Men inte av
Jag fattar att avrundingen väljer det minst positiva värdet när den avrundat till närmaste heltal, men den borde gå mot noll istället.
Vad är det jag inte fattar?
SV: Modulo och python
Postat: 12 dec 2007, 10:18
av gasol
Python avrundar neråt vid heltalsdivision...
4/3 ~ 1.3333333333333333 eller 1 + (1/3)
floor(1.3333333) = 1
floor(-1.3333333) = -2
-(4/3) ger bara -(1) där 1 är resultatet av 4/3
4.0 / 3.0 kommer att producera rätt resultat.
SV: Modulo och python
Postat: 12 dec 2007, 22:02
av Niklas Bolmdahl
gasol skrev:
Python avrundar neråt vid heltalsdivision...
4/3 ~ 1.3333333333333333 eller 1 + (1/3)
floor(1.3333333) = 1
floor(-1.3333333) = -2
-(4/3) ger bara -(1) där 1 är resultatet av 4/3
Jo, det där fattade jag redan. Min fråga var ju snarare
varför.
Poängen är ju att inom ramarna för de olika datatyperna, så borde matten i språket ändå vara rimligt lik riktig matte, och en avrundning neråt borde snarast gå mot noll. Vad jag undrar över är
varför det inte funkar så.
Floor-funtionen, är det en riktig funktion eller något du skrev i ett försökt att förtydliga? (hittar den inte, vad måste jag importera i så fall?)
Skulle gärna vilja se vad den gör i detalj om det är en faktisk funktion.
SV: Modulo och python
Postat: 12 dec 2007, 22:09
av Konservburk
dacovale skrev:
Floor-funtionen, är det en riktig funktion eller något du skrev i ett försökt att förtydliga? (hittar den inte, vad måste jag importera i så fall?)
Skulle gärna vilja se vad den gör i detalj om det är en faktisk funktion.
Floor-funktionen är en "riktig" funktion:
http://mathworld.wolfram.com/FloorFunction.html
SV: Modulo och python
Postat: 12 dec 2007, 22:25
av gasol
dacovale skrev:
gasol skrev:
Python avrundar neråt vid heltalsdivision...
4/3 ~ 1.3333333333333333 eller 1 + (1/3)
floor(1.3333333) = 1
floor(-1.3333333) = -2
-(4/3) ger bara -(1) där 1 är resultatet av 4/3
Jo, det där fattade jag redan. Min fråga var ju snarare
varför.
Poängen är ju att inom ramarna för de olika datatyperna, så borde matten i språket ändå vara rimligt lik riktig matte, och en avrundning neråt borde snarast gå mot noll. Vad jag undrar över är
varför det inte funkar så.
Floor-funtionen, är det en riktig funktion eller något du skrev i ett försökt att förtydliga? (hittar den inte, vad måste jag importera i så fall?)
Skulle gärna vilja se vad den gör i detalj om det är en faktisk funktion.
Skulle förmodligen tro att det är ett arv från C.
Flyttalsoperationer tar 1000000 gånger så mycket mer tid att exekuvera för tid dator and vad heltalsoperationer, speciellt division.
Heltal och flyttal lagras på två vitt skiljda sätt i din dator. (
http://en.wikipedia.org/wiki/IEEE_float ... t_standard)
Jämnför ALU (Arithmetic logic unit)
http://en.wikipedia.org/wiki/Arithmetic_logic_unit
med FPU (Floating point unit)
http://en.wikipedia.org/wiki/Floating_point_unit
Jag har ingen aning om floor finns i python eller inte, men en enkelt implementation av floor skulle vara detta:
(int)(x)
dvs konvertera till en int, konverteringen till en int sker med avkapning, inte avrundning. hur man nu skriver det som en funktion i python är dock ett mysterium.
SV: Modulo och python
Postat: 12 dec 2007, 22:26
av Lars
dacovale skrev:
Poängen är ju att inom ramarna för de olika datatyperna, så borde matten i språket ändå vara rimligt lik riktig matte, och en avrundning neråt borde snarast gå mot noll.
Det jag tror att du menar brukar kallas
trunkering, d.v.s. att man bara hugger av decimalerna.
Funktionen floor() finns i modulen math.
SV: Modulo och python
Postat: 12 dec 2007, 23:06
av Niklas Bolmdahl
men om konvertering till int sker med trunkering / avkapning, så borde ju -4/3 bli -1, eftersom -4.0/3 blir -1.3333....
det är ju just det jag inte fattar, hur en trunkering av -1.3333.... kan bli -2
SV: Modulo och python
Postat: 12 dec 2007, 23:36
av gasol
Kod: Markera allt
#include <stdio.h>
int main(int argc, char **argv) {
printf("%d %d\n", 4/3, 4/(-3));
return 0;
}
Skriver ut
1 -1, du har rätt i att det inte är någon trunkering som sker, utan att floor anropas i Python, kodar inte i python men som sagt en avkapning hade inte brytt sig om tecknet
Googlade lite på det hela och hittade detta:
The most controversial change in Python 2.2 heralds the start of an effort to fix an old design flaw that's been in Python from the beginning. Currently Python's division operator, /, behaves like C's division operator when presented with two integer arguments: it returns an integer result that's truncated down when there would be a fractional part. For example, 3/2 is 1, not 1.5, and (-1)/2 is -1, not -0.5. This means that the results of divison can vary unexpectedly depending on the type of the two operands and because Python is dynamically typed, it can be difficult to determine the possible types of the operands.
(The controversy is over whether this is really a design flaw, and whether it's worth breaking existing code to fix this. It's caused endless discussions on python-dev, and in July 2001 erupted into an storm of acidly sarcastic postings on comp.lang.python. I won't argue for either side here and will stick to describing what's implemented in 2.2. Read PEP 238 for a summary of arguments and counter-arguments.)
Lite mer från sidan:
http://www.python.org/doc/2.2.3/whatsnew/node7.html
SV: Modulo och python
Postat: 12 dec 2007, 23:52
av Lars
Grejen är att det finns en mängd olika sätt att avrunda på. Ibland är det viktigt att man använder exakt rätt metod, ibland spelar det kanske inte så stor roll. Hur som helst är det bra att känna till de olika metoderna:
- Avrunding uppåt: går mot ∞, funktionen math.ceil()
- Avrunding neråt: går mot -∞, funktionen math.floor()
- Trunkering: går mot 0, funktionen int()
- Avrundning till närmsta heltal: funktionen round()
Division mellan heltal innebär avrundning neråt. Som gasol nämnde så har det här diskuterats ganska mycket och från och med Python 3.0 kommer divisionsoperatorn alltid att returnera ett flyttal. Man kan få det så redan nu genom att använda "from __future__ import division". Dessutom finns operatorn // som kommer att fortsätta fungera precis som / gör nu, även i Python 3.0.
SV: Modulo och python
Postat: 13 dec 2007, 09:29
av Niklas Bolmdahl
Ok, så då får jag helt enkelt vara noggrann med att specifiera vad det är jag vill ha. I det här fallet vill jag ju ha trunkering, så då får jag väl helt enkelt specifiera med int(4/(-3)), eller kanske då snarare int(4//(-3)). Om jag fattat rätt så kommer 3.0 vara här om ungefär ett år. Kanske lika bra att börja lära sig koda enligt 3.0 på en gång.
Är väl egentligen inte mycket mer än att vänja sig vid att det är floor som anropas istället för att resultatet trunkeras. Skulle bara vilja ha vetat varför. (Om de hade behövt skådespelare till en ny Ronja Rövardotter-film, skulle jag söka till o bli en sån där "Vaffö' då då"-minipyssling)
SV: Modulo och python
Postat: 13 dec 2007, 10:28
av Niklas Bolmdahl
Kod: Markera allt
>>> int(4//(-3))
-2
>>> round(4//(-3))
-2.0
>>> int(4/(-3))
-2
>>> round(4/(-3))
-2.0
>>> int(4/3)
1
>>> round(4/3)
1.0
>>> 9/5.0
1.8
>>> round(9/5)
1.0
tyvärr. Sitter hemma hos en kompis, så var tvungen att dra ner o installera python (winXP...)
round verkar ju nästan roligast av allt. som jag fattar round, så tar round det redan färdig-uträknade, floorade värdet, och gör det till ett flyttal.
EDIT2: round fungerar som Lars säger, men om man skickar en heltals-division så skickar man ju inte divisionen i sig, utan enbart det färdiguträknade värdet.
finns det nåt sätt att undvika floor och istället få en trunkering?
EDIT: ja.
Kod: Markera allt
>>> tal1 = float(raw_input("Skriv ett tal: "))
Skriv ett tal: -4
>>> tal2 = float(raw_input("Skriv ett till tal: "))
Skriv ett till tal: 3
>>> trunkerad = int(tal1/tal2)
>>> print trunkerad
-1
men det känns bakvänt att vara tvungen att använda flyttal för att få trunkering.
får nog dock betrakta mitt problem med att tvinga trunkering som löst.