www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - 10^2 = 99 ???

reply Florian Sonnenberger <florian sonnenberger-wolnzach.de> writes:
I've ever thought 10^2 is 100, but in

std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, cast(real)2 ))

it's 99.

A strage error, because
   std.stdio.writefln( std.math.pow( 10, cast(real)2 ))  is 100
and
   std.stdio.writefln( cast(int)100.0 ) also is 100

(DMD 0.121 / WinXP)

Florian
Apr 30 2005
parent reply Florian Sonnenberger <florian sonnenberger-wolnzach.de> writes:
Florian Sonnenberger wrote:
 I've ever thought 10^2 is 100, but in
 
 std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, cast(real)2 ))
 
 it's 99.
 
 A strage error, because
   std.stdio.writefln( std.math.pow( 10, cast(real)2 ))  is 100
 and
   std.stdio.writefln( cast(int)100.0 ) also is 100
 
 (DMD 0.121 / WinXP)
 
 Florian
You could also just write std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, 2.0 )) Florian
Apr 30 2005
next sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Florian Sonnenberger <florian sonnenberger-wolnzach.de> wrote:

[...]
 std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, 2.0 ))
This seems to be a dmc bug. gdc prints 100. -manfred
Apr 30 2005
prev sibling parent reply "Walter" <newshound digitalmars.com> writes:
"Florian Sonnenberger" <florian sonnenberger-wolnzach.de> wrote in message
news:d50bci$nn6$1 digitaldaemon.com...
 Florian Sonnenberger wrote:
 I've ever thought 10^2 is 100, but in

 std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, cast(real)2 ))

 it's 99.
pow() uses floating point math, which is inexact. Converting a floating point value to integer involves chopping, not rounding, so: cast(int)99.99 will be 99, not 100.
Apr 30 2005
parent reply Florian Sonnenberger <florian sonnenberger-wolnzach.de> writes:
Walter wrote:
 "Florian Sonnenberger" <florian sonnenberger-wolnzach.de> wrote in message
 news:d50bci$nn6$1 digitaldaemon.com...
 
Florian Sonnenberger wrote:

I've ever thought 10^2 is 100, but in

std.stdio.writefln( "10^2=", cast(int)std.math.pow( 10, cast(real)2 ))

it's 99.
pow() uses floating point math, which is inexact. Converting a floating point value to integer involves chopping, not rounding, so: cast(int)99.99 will be 99, not 100.
I tested the powers of 0^0 till 20^20 and many of them were right. But ~22% were wrong. I thought if conversion is inexact then all results were wrong. Some of them had also bigger differeces from the right result, for example 12^17, 15^16, 17^15, 18^15, 20^14. I had some formatting problems, that's why the list of the wrong ones is attached. I don't know if this is really a bug but please have a short look at it. Anyway, could you add the following function to std.math? It's your real pow(real x, uint n) but returns a long integer. long pow(int x, uint n) { long p; switch (n) { case 0: p = 1; break; case 1: p = x; break; case 2: p = x * x; break; default: p = 1; while (1) { if (n & 1) p *= x; n >>= 1; if (!n) break; x *= x; } break; } return p; } Thanks, Florian
Apr 30 2005
parent reply "Walter" <newshound digitalmars.com> writes:
"Florian Sonnenberger" <florian sonnenberger-wolnzach.de> wrote in message
news:d516fe$1g41$1 digitaldaemon.com...
 Walter wrote:
 "Florian Sonnenberger" <florian sonnenberger-wolnzach.de> wrote in
message
 news:d50bci$nn6$1 digitaldaemon.com...
 pow() uses floating point math, which is inexact. Converting a floating
 point value to integer involves chopping, not rounding, so:

     cast(int)99.99 will be 99, not 100.
I tested the powers of 0^0 till 20^20 and many of them were right. But ~22% were wrong. I thought if conversion is inexact then all results were wrong.
All of the results have roundoff error. Sometimes it rounds off to the 'correct' value, but it still has roundoff error in it. To see the magnitude of the error, you can do things like: std.math.pow( 10, cast(real)2 )) - 100
 Some of them had also bigger differeces from the right result, for
 example 12^17, 15^16, 17^15, 18^15, 20^14.
 I had some formatting problems, that's why the list of the wrong ones is
 attached. I don't know if this is really a bug but please have a short
 look at it.
It isn't a bug. Roundoff error is a fact of life with floating point math.
 Anyway, could you add the following function to std.math?
 It's your  real pow(real x, uint n)  but returns a long integer.

 long pow(int x, uint n)
This would unfortunately have overloading problems with the other pow()s that return a real.
Apr 30 2005
parent Derek Parnell <derek psych.ward> writes:
On Sat, 30 Apr 2005 21:11:03 -0700, Walter wrote:


[snip]

 Anyway, could you add the following function to std.math?
 It's your  real pow(real x, uint n)  but returns a long integer.

 long pow(int x, uint n)
This would unfortunately have overloading problems with the other pow()s that return a real.
Agreed, but its still dumb, IMNSHO ;-) So why not insert it into the std.math module with a different name, as that seems to be the approved way of "overloading" return values. Maybe ... long pow_l(int, unit); -- Derek Parnell Melbourne, Australia 1/05/2005 7:51:15 PM
May 01 2005