Daniil Troshkov via llvm-dev
2017-Mar-21 17:10 UTC
[llvm-dev] [question] с-double: 35.7 * 100 vs 3570.0
Hi all! There is a simple c code: double a = 3570.0; double b = 35.7 * 100; int main () { if (b != a) return 1; return 0; } It returns 1 due to: 40abe400 00000000 //a = 3570.0 40abe400 00000001 //b = 35.7 * 100; gcc do the same thing, so I think it's ok but why? For floats: float a = 3570.0; float b = 35.7 * 100; int main () { if (b != a) return 1; return 0; } It returns 0... 455f2000 //a = 3570.0 455f2000 //b = 35.7 * 100; I will be grateful to get any explanations. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170321/60d8fef3/attachment.html>
Matthias Braun via llvm-dev
2017-Mar-21 17:18 UTC
[llvm-dev] [question] с-double: 35.7 * 100 vs 3570.0
Floating point arithmetic is not intuitive. http://www.lsi.upc.edu/~robert/teaching/master/material/p5-goldberg.pdf is a good introduction to the common pitfalls. TL;DR 35.7 cannot be represented exactly as a floating point number. - Matthias> On Mar 21, 2017, at 10:10 AM, Daniil Troshkov via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > Hi all! > > There is a simple c code: > > double a = 3570.0; > double b = 35.7 * 100; > int main () > { > if (b != a) return 1; > return 0; > } > > It returns 1 due to: > 40abe400 00000000 //a = 3570.0 > 40abe400 00000001 //b = 35.7 * 100; > > gcc do the same thing, so I think it's ok but why? > > For floats: > > float a = 3570.0; > float b = 35.7 * 100; > int main () > { > if (b != a) return 1; > return 0; > } > > It returns 0... > 455f2000 //a = 3570.0 > 455f2000 //b = 35.7 * 100; > > I will be grateful to get any explanations. > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Daniil Troshkov via llvm-dev
2017-Mar-21 17:28 UTC
[llvm-dev] [question] с-double: 35.7 * 100 vs 3570.0
Thank you! On Tue, Mar 21, 2017 at 8:18 PM, Matthias Braun <mbraun at apple.com> wrote:> Floating point arithmetic is not intuitive. http://www.lsi.upc.edu/~ > robert/teaching/master/material/p5-goldberg.pdf is a good introduction to > the common pitfalls. > > TL;DR 35.7 cannot be represented exactly as a floating point number. > > - Matthias > > > On Mar 21, 2017, at 10:10 AM, Daniil Troshkov via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > > > > Hi all! > > > > There is a simple c code: > > > > double a = 3570.0; > > double b = 35.7 * 100; > > int main () > > { > > if (b != a) return 1; > > return 0; > > } > > > > It returns 1 due to: > > 40abe400 00000000 //a = 3570.0 > > 40abe400 00000001 //b = 35.7 * 100; > > > > gcc do the same thing, so I think it's ok but why? > > > > For floats: > > > > float a = 3570.0; > > float b = 35.7 * 100; > > int main () > > { > > if (b != a) return 1; > > return 0; > > } > > > > It returns 0... > > 455f2000 //a = 3570.0 > > 455f2000 //b = 35.7 * 100; > > > > I will be grateful to get any explanations. > > > > > > _______________________________________________ > > LLVM Developers mailing list > > llvm-dev at lists.llvm.org > > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170321/59086769/attachment.html>
Bruce Hoult via llvm-dev
2017-Mar-22 09:49 UTC
[llvm-dev] [question] с-double: 35.7 * 100 vs 3570.0
Your problem is that while 35.7 looks nice and neat in decimal -- it's 357/10 -- computers store numbers in binary. In the case of IEEE double precision floating point it will be stored as 5024328334285210/2^47 which is 5024328334285210/140737488355328. That's the nearest you can do in binary floating point with a 53 bit mantissa. Multiply by 100 and you get 502432833428521000/140737488355328, which if you work it out is 3570, with 40 left over. Which is not exactly 3570. But it's close. If you need more accurate than that you should use fractions (in fact, "bignum" fractions), not floating point. On Tue, Mar 21, 2017 at 8:10 PM, Daniil Troshkov via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi all! > > There is a simple c code: > > double a = 3570.0; > double b = 35.7 * 100; > int main () > { > if (b != a) return 1; > return 0; > } > > It returns 1 due to: > 40abe400 00000000 //a = 3570.0 > 40abe400 00000001 //b = 35.7 * 100; > > gcc do the same thing, so I think it's ok but why? > > For floats: > > float a = 3570.0; > float b = 35.7 * 100; > int main () > { > if (b != a) return 1; > return 0; > } > > It returns 0... > 455f2000 //a = 3570.0 > 455f2000 //b = 35.7 * 100; > > I will be grateful to get any explanations. > > > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170322/ee184bf3/attachment.html>
Seemingly Similar Threads
- [LLVMdev] [llvm][SelectionDAG] trivial patch: fix misprint in SelectionDAGLegalize::ExpandInsertToVectorThroughStack
- [LLVMdev] [llvm][SelectionDAG] trivial patch: fix misprint in SelectionDAGLegalize::ExpandInsertToVectorThroughStack
- [LLVMdev] [LLVM Doc] tblgen backends
- [LLVMdev] [LLVM Doc] tblgen backends
- [LLVMdev] [llvm] [libunwind] r207467 misprint