Wolfram|Alpha says sin(2**64 rad) = 0.0235985 too. However, on my machine, I get the following:
- Python 3.4.3 (32-bit, compiled with MSVC),
sin(2.0**64)
= 0.2472606463094177
- Rust nightly (32-bit),
2.0f32.powf(64.0).sin()
= 0.31282133
- Rust nightly (32-bit),
2.0f64.powf(64.0).sin()
= -0.35464734997014274
- gcc 4.8.1 (32-bit),
sin(powf(2.0, 64.0))
= 0.023599
- gcc 4.9.0 (64-bit),
sin(powf(2.0, 64.0))
= 0.023599
- clang 3.4.2 (64-bit),
sin(powf(2.0, 64.0))
= 0.312821
- Windows 7 calc (:P),
2 ^ 64 sin
= 0.27563735581699…
Going a bit further and looking at the generated machine code, the GCC version has this:
...
movabsq $4582459028794800445, %rax
...
In constrast, the clang version has this:
...
movss .LCPI0_0(%rip), %xmm0
movss .LCPI0_1(%rip), %xmm1
callq powf
cvtss2sd %xmm0, %xmm0
callq sin
...
In other words, GCC is computing the result during compilation, whereas clang is computing it at runtime. Passing -O0
doesn’t appear to suppress this behaviour. Passing -O3
to clang causes it to emit this:
...
movss .LCPI0_0(%rip), %xmm0
callq exp2f
cvtss2sd %xmm0, %xmm0
callq sin
...
I wasn’t able to convince clang to produce the same code as GCC.
Edit Bonus round: let’s ask playbot
on the IRC channel what it thinks:
- playbot: (2.0f32.powf(64.0).sin(), 2.0f64.powf(64.0).sin())
- (0.02359851, 0.023598509904439558)
- playbot: VERSION
- "rustc 1.2.0 (082e47636 2015-08-03)"
Playbot is running on x86_64
linux… what’s interesting is that it’s producing the above at runtime. So it’s ostensibly doing the same thing as clang
on my machine… except it’s giving radically different results. Wat.
Having downloaded the latest 64-bit nightly, I get:
C:\Users\drk>rustc -vV
rustc 1.4.0-nightly (e5d90d984 2015-08-07)
binary: rustc
commit-hash: e5d90d98402475b6e154ce216f9efcb80da1a747
commit-date: 2015-08-07
host: x86_64-pc-windows-gnu
release: 1.4.0-nightly
C:\Users\drk>cargo script --expr "(2.0f32.powf(64.0).sin(), 2.0f64.powf(64.0).sin())"
Compiling expr v0.1.0 (file:///C:/Users/drk/AppData/Local/Cargo/script-cache/expr-a58832b99c8d4fdd)
(0.31282133, -0.35464734997014274)
So… Rust is consistent on the same platform, but not on the same architecture. Wat?