Strange double to uint conversion

Steven Schveighoffer schveiguy at gmail.com
Mon Nov 18 21:54:53 UTC 2019


On 11/18/19 4:08 PM, Luiz Silveira wrote:
> Hello, everyone!
> 
>    I'm a new D fan, still learning the language and this is my first post.
> 
>    I came up with a strange behavior, using D 2.089 for windows.
> 
>    Considering the program "error.d":
> 
> import std.stdio;
> import std.conv;
> 
> void main() {
>          uint c(double v) {
>                  return (37.05*100.0).to!uint;
>          }
> 
>          double f;
>          uint c2(double v) {
>                  return (37.05*f).to!uint;
>          }
>          f=100.0;
> 
>          writeln("All should be 3705, right? -- ", 37.05*100, "; ", 
> 37.05*100.0, "; ", (37.05*100).to!uint, "; ",c(37.05),"; ",c2(37.05));
> }
> 
>    I expect all values to be 3705, yet running it with 
> '/c/D/dmd-2.089.0/windows/bin/dmd.exe -run error.d' gives me the output:
> 
> All should be 3705, right? -- 3705; 3705; 3705; 3705; 3704
> 
>    I also played with several compilation options, all yelding the same 
> results:
> 
> dmd -boundscheck=on -m64 -lowmem -of="error" "error".d && ./error
> dmd -boundscheck=off -m64 -lowmem -of="error" "error".d && ./error
> dmd -boundscheck=on -m32 -lowmem -of="error" "error".d && ./error
> dmd -release -O -mcpu=native -boundscheck=on -m64 -lowmem -of="error" 
> "error".d && ./error
> dmd -release -O -mcpu=native -boundscheck=on -m64 -of="error" "error".d 
> && ./error
> dmd -of="error" "error".d && ./error
> 
>    What am I doing wrong?

You are expecting floating point to behave as if it is stored as a 
decimal number. It's not.

An interesting thing is that 5/100 (or 1/20) is not accurately 
representable in floating point. So you get an approximation in some 
cases (actually in all cases), but happens to print the right thing.

What you may want to do is use std.math.ceil.

-Steve


More information about the Digitalmars-d-learn mailing list