[Pharo-project] Unexpected behavior of roundTo:
2.8011416510246336 roundTo: 0.01 returns 2.8000000000000003 Tested with 1.2 Should I fill a ticket, I don't see anythings similar? Hilaire -- Education 0.2 -- http://blog.ofset.org/hilaire
It looks like a known issue: printShowingDecimalPlaces: placesDesired "This implementation avoids any rounding error caused by rounded or roundTo: " ^ self asTrueFraction printShowingDecimalPlaces: placesDesired Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Even better: 2.8 truncateTo: 0.01 -> 2.8000000000000003 Le 08/04/2011 18:52, Hilaire Fernandes a écrit :
It looks like a known issue:
printShowingDecimalPlaces: placesDesired "This implementation avoids any rounding error caused by rounded or roundTo: " ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Yes nice example to exhibit in school This again happens even if performed exactly (then rounded to nearest Float) (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat As soon as you write 0.01 instead of (1/100) or (0.01s2), the worm is in the fruit. Nicolas 2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
Even better:
2.8 truncateTo: 0.01 -> 2.8000000000000003
Le 08/04/2011 18:52, Hilaire Fernandes a écrit :
It looks like a known issue:
printShowingDecimalPlaces: placesDesired    "This implementation avoids any rounding error caused by rounded or roundTo: "    ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
 2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Nicolas would not you like the write (I can help) a two three 5 pages document for the next book on this topics? :) I would be gorgeous and everybody would love that Stef On Apr 8, 2011, at 7:18 PM, Nicolas Cellier wrote:
Yes nice example to exhibit in school
This again happens even if performed exactly (then rounded to nearest Float) (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat
As soon as you write 0.01 instead of (1/100) or (0.01s2), the worm is in the fruit.
Nicolas
2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
Even better:
2.8 truncateTo: 0.01 -> 2.8000000000000003
Le 08/04/2011 18:52, Hilaire Fernandes a écrit :
It looks like a known issue:
printShowingDecimalPlaces: placesDesired "This implementation avoids any rounding error caused by rounded or roundTo: " ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Once more, Floats are inexact. 0.01 ~= 0.01s2 The name #absPrintExactlyOn:base: is lying, it does not print exactly, but it prints the shortest decimal representation than will be rounded to the same Float when read back. To print it exactly, you need to use #printShowingDecimalPlaces: indeed. As every finite Float is a represented internally as a Fraction with a denominator being a power of 2, every finite Float has a decimal representation with a finite number of decimals digits (just multiply numerator and denominator with adequate power of 5, and you'll get the digits). So try: 0.01 printShowingDecimalPlaces: 59 -> 0.01000000000000000020816681711721685132943093776702880859375 You see that even if you try to execute the operation without rounding error, then convert it back to Float, you get the error: (2.8011416510246336 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat -> 2.8000000000000003 When you perform the #roundTo: operations in Float inexact arithmetic, you may accumulate more rounding errors, so the result may vary. If you want to round to an exact hundredth, then use exact arithmetic and try: 2.8011416510246336 roundTo: 0.01s2 Hope it helps to consider Float for what they are, inexact but fast. Don't put too much expectations on them. Nicolas 2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
It looks like a known issue:
printShowingDecimalPlaces: placesDesired     "This implementation avoids any rounding error caused by rounded or roundTo: "     ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
 2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
+1. This seems like an extension of "never test equality on floats." ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Nicolas Cellier [nicolas.cellier.aka.nice@gmail.com] Sent: Friday, April 08, 2011 1:14 PM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] Unexpected behavior of roundTo: Once more, Floats are inexact. 0.01 ~= 0.01s2 The name #absPrintExactlyOn:base: is lying, it does not print exactly, but it prints the shortest decimal representation than will be rounded to the same Float when read back. To print it exactly, you need to use #printShowingDecimalPlaces: indeed. As every finite Float is a represented internally as a Fraction with a denominator being a power of 2, every finite Float has a decimal representation with a finite number of decimals digits (just multiply numerator and denominator with adequate power of 5, and you'll get the digits). So try: 0.01 printShowingDecimalPlaces: 59 -> 0.01000000000000000020816681711721685132943093776702880859375 You see that even if you try to execute the operation without rounding error, then convert it back to Float, you get the error: (2.8011416510246336 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat -> 2.8000000000000003 When you perform the #roundTo: operations in Float inexact arithmetic, you may accumulate more rounding errors, so the result may vary. If you want to round to an exact hundredth, then use exact arithmetic and try: 2.8011416510246336 roundTo: 0.01s2 Hope it helps to consider Float for what they are, inexact but fast. Don't put too much expectations on them. Nicolas 2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
It looks like a known issue:
printShowingDecimalPlaces: placesDesired "This implementation avoids any rounding error caused by rounded or roundTo: " ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Pour enfoncer le clou, let's play a bit more with inexact representations: { ((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8 predecessor)) abs -> -1. ((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8)) abs -> 0. ((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8 successor)) abs -> 1. } detectMin: [:e | e key ] you get 0.0->1, which mean that: (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat = (2.8 successor) But remember: (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) ~= (2.8 successor) It must be interpreted as: the nearest Float to (2.8 asTrueFraction roundTo: 0.01 asTrueFraction) is (2.8 successor). If you want to know how far it is, then get an idea with: ((2.8 asTrueFraction roundTo: 0.01 asTrueFraction) - (2.8 successor) asTrueFraction) asFloat -2.0816681711721685e-16 Nicolas 2011/4/8 Schwab,Wilhelm K <bschwab@anest.ufl.edu>:
+1. Â This seems like an extension of "never test equality on floats."
________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Nicolas Cellier [nicolas.cellier.aka.nice@gmail.com] Sent: Friday, April 08, 2011 1:14 PM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] Unexpected behavior of roundTo:
Once more, Floats are inexact. Â Â 0.01 ~= 0.01s2 The name #absPrintExactlyOn:base: is lying, it does not print exactly, but it prints the shortest decimal representation than will be rounded to the same Float when read back.
To print it exactly, you need to use #printShowingDecimalPlaces: indeed. As every finite Float is a represented internally as a Fraction with a denominator being a power of 2, every finite Float has a decimal representation with a finite number of decimals digits (just multiply numerator and denominator with adequate power of 5, and you'll get the digits).
So try: 0.01 printShowingDecimalPlaces: 59 -> 0.01000000000000000020816681711721685132943093776702880859375
You see that even if you try to execute the operation without rounding error, then convert it back to Float, you get the error: Â (2.8011416510246336 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat -> Â 2.8000000000000003
When you perform the #roundTo: operations in Float inexact arithmetic, you may accumulate more rounding errors, so the result may vary.
If you want to round to an exact hundredth, then use exact arithmetic and try: Â 2.8011416510246336 roundTo: 0.01s2
Hope it helps to consider Float for what they are, inexact but fast. Don't put too much expectations on them.
Nicolas
2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
It looks like a known issue:
printShowingDecimalPlaces: placesDesired     "This implementation avoids any rounding error caused by rounded or roundTo: "     ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
 2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
Well, whatever the underneath representation, one can expect roundedTo: 2 to return a float with two decimals. I am only interested in roundedTo: to display in the DrGeo canvas numbers. It was still funny to see sometimes number with 10 digits. Thanks for the info. Hilaire -- Education 0.2 -- http://blog.ofset.org/hilaire
2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
Well, whatever the underneath representation, one can expect roundedTo: 2 to return a float with two decimals.
I am only interested in roundedTo: to display in the DrGeo canvas numbers. It was still funny to see sometimes number with 10 digits.
Thanks for the info.
Hilaire
Previous versions were lying too by not printing a number that would be reinterpreted into itself. But if it is what you want, then you should use the old print message, #absPrintOn:base: Maybe it could be wrapped into a printApproximatelyOn: to be polymorphic with other numbers ? Nicolas
-- Education 0.2 -- http://blog.ofset.org/hilaire
2011/4/8 Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com>:
Once more, Floats are inexact. Â Â 0.01 ~= 0.01s2 The name #absPrintExactlyOn:base: is lying, it does not print exactly, but it prints the shortest decimal representation than will be rounded to the same Float when read back.
To print it exactly, you need to use #printShowingDecimalPlaces: indeed. As every finite Float is a represented internally as a Fraction with a denominator being a power of 2, every finite Float has a decimal representation with a finite number of decimals digits (just multiply numerator and denominator with adequate power of 5, and you'll get the digits).
So try: 0.01 printShowingDecimalPlaces: 59 -> 0.01000000000000000020816681711721685132943093776702880859375
Oh one thing I forgot, you wanna know how many digits you need after decimal point to print exactly ? Easy, (0.01 asTrueFraction denominator highBit - 1). Nicolas
On Apr 8, 2011, at 7:14 PM, Nicolas Cellier wrote:
Once more, Floats are inexact. 0.01 ~= 0.01s2 The name #absPrintExactlyOn:base: is lying, it does not print exactly, but it prints the shortest decimal representation than will be rounded to the same Float when read back.
we should update the comment if it does not reflect that.
To print it exactly, you need to use #printShowingDecimalPlaces: indeed. As every finite Float is a represented internally as a Fraction with a denominator being a power of 2, every finite Float has a decimal representation with a finite number of decimals digits (just multiply numerator and denominator with adequate power of 5, and you'll get the digits).
So try: 0.01 printShowingDecimalPlaces: 59 -> 0.01000000000000000020816681711721685132943093776702880859375
You see that even if you try to execute the operation without rounding error, then convert it back to Float, you get the error: (2.8011416510246336 asTrueFraction roundTo: 0.01 asTrueFraction) asFloat -> 2.8000000000000003
When you perform the #roundTo: operations in Float inexact arithmetic, you may accumulate more rounding errors, so the result may vary.
If you want to round to an exact hundredth, then use exact arithmetic and try: 2.8011416510246336 roundTo: 0.01s2
Hope it helps to consider Float for what they are, inexact but fast. Don't put too much expectations on them.
Yes!
Nicolas
2011/4/8 Hilaire Fernandes <hilaire.fernandes@gmail.com>:
It looks like a known issue:
printShowingDecimalPlaces: placesDesired "This implementation avoids any rounding error caused by rounded or roundTo: " ^ self asTrueFraction printShowingDecimalPlaces: placesDesired
Le 08/04/2011 18:47, Hilaire Fernandes a écrit :
2.8011416510246336 roundTo: 0.01
returns
2.8000000000000003
Tested with 1.2
Should I fill a ticket, I don't see anythings similar?
Hilaire
-- Education 0.2 -- http://blog.ofset.org/hilaire
participants (4)
-
Hilaire Fernandes -
Nicolas Cellier -
Schwab,Wilhelm K -
Stéphane Ducasse