Thread overview
10^2 = 99 ???
Apr 30, 2005
Manfred Nowak
Apr 30, 2005
Walter
May 01, 2005
Walter
May 01, 2005
Derek Parnell
April 30, 2005
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
April 30, 2005
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
April 30, 2005
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
April 30, 2005
"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.


May 01, 2005
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


May 01, 2005
"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.


May 01, 2005
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