Post A9O2ERptNVa8bWp1DE by urusan@fosstodon.org
 (DIR) More posts by urusan@fosstodon.org
 (DIR) Post #A9Nu3InDrPZ9jskPAW by urusan@fosstodon.org
       2021-07-17T15:58:04Z
       
       0 likes, 0 repeats
       
       Programming Challenge: Find a concrete case where using a Double/Float64 causes issues for a realistic money use case.An answer might look like:5.01+7.11*2 == 19.23Where it does not return the correct answer (but this one works fine).
       
 (DIR) Post #A9NukOBLhQvUuBZt6O by peter@mastodon.peterbabic.dev
       2021-07-17T16:05:51Z
       
       0 likes, 0 repeats
       
       @urusan I suspect this is implementation dependent, but I might be wrong
       
 (DIR) Post #A9NuqihUKFYQHNd5cW by wizzwizz4@fosstodon.org
       2021-07-17T16:06:59Z
       
       0 likes, 0 repeats
       
       @urusan let mut total = 0.0f64;for (item, count) in order {    total += system.lookup_price(item) * count;}let change = paid - total;if change < 0.0 {    return Err("underpaid");}system.refund(change)?;system.fulfil(order)?;system.commit()
       
 (DIR) Post #A9NvWc0Pbgmdg7SNAe by urusan@fosstodon.org
       2021-07-17T16:14:35Z
       
       0 likes, 0 repeats
       
       @peter IEEE 754 is standard, so most implementations should agree.I do know that 64-bit floating point numbers can represent any realistic money amount, so if there is a problem it would be due to floating point arithmetic.This challenge is based on the common idea that a double value is unsuitable for use with money, which might be true, or it might be an artifact of the days when 32-bit float was king.
       
 (DIR) Post #A9NvkuhGuTVrhcK6z2 by urusan@fosstodon.org
       2021-07-17T16:17:09Z
       
       0 likes, 0 repeats
       
       @wizzwizz4 What numbers does system.lookup_price(item) return? Or should this work for any reasonable prices?
       
 (DIR) Post #A9Nw0dzkm6cmXHT8ee by wizzwizz4@fosstodon.org
       2021-07-17T16:19:54Z
       
       0 likes, 0 repeats
       
       @urusan This will start getting non-integer penny values for any reasonably-sized order, if system.lookup_price(item) returns non-power-of-two-fraction floats. After that, correctness depends on the rounding mode, which is usually program-global.
       
 (DIR) Post #A9NxOSwBdcPt95ivKq by wizzwizz4@fosstodon.org
       2021-07-17T16:24:25Z
       
       0 likes, 0 repeats
       
       @urusan In the extreme case, virtually all orders of around 3×10³⁰ items will give an incorrect result, but a maliciously-selected order could cause problems before then.And that's assuming rounding's actually being done. If not, refunding the change (say) could crash something.If rounding's done differently in different places, your program is not just mischarging; it's committing financial fraud.
       
 (DIR) Post #A9NxOTPbsDx6cLUQCG by urusan@fosstodon.org
       2021-07-17T16:35:30Z
       
       0 likes, 0 repeats
       
       @wizzwizz4 While this is one of the better approaches I've seen, I'm still skeptical it would be a problem if actually run with any realistic values. Sure, if someone bought 10³⁰ items and had $10³⁰ to buy all that with, you would definitely have a problem, but what if you were limited to $1 quadrillion?Could you write something that generates realistic values that cause an issue?I'm fine with it being off by <0.01, as I consider that a problem even if rounding can solve it
       
 (DIR) Post #A9NxifN57RqXV3w54q by wizzwizz4@fosstodon.org
       2021-07-17T16:39:08Z
       
       0 likes, 0 repeats
       
       @urusan If there were 10³⁰ purchases and 10³⁰ discounts, so the ultimate value was somewhere around $10, the calculated answer would probably be wrong.If you're fine with it being off by a small amount, easy:10 × PENCIL@$0.012 × RUBBER@$0.35This gives the wrong value with floats.
       
 (DIR) Post #A9O0R2xWysfpJ4H5ge by peter@mastodon.peterbabic.dev
       2021-07-17T17:09:36Z
       
       0 likes, 0 repeats
       
       @urusan
       
 (DIR) Post #A9O2ERIDOidwv547ii by Agris@blob.cat
       2021-07-17T17:17:36.994661Z
       
       0 likes, 0 repeats
       
       @urusan @wizzwizz4 What I’ve always done is set it as a float but with fixed precision on the matissa and a maximum value of money the system could process.
       
 (DIR) Post #A9O2ERptNVa8bWp1DE by urusan@fosstodon.org
       2021-07-17T17:29:43Z
       
       0 likes, 0 repeats
       
       @Agris @wizzwizz4 I didn't know that fixing precision on the mantissa was an option.
       
 (DIR) Post #A9O3nycVZytiN84DNw by vrdhn@fosstodon.org
       2021-07-17T17:47:21Z
       
       0 likes, 0 repeats
       
       @urusan Which language, except perhaps scheme, has fraction as a first class number ?
       
 (DIR) Post #A9O5lZhpRFhAQnXPqy by urusan@fosstodon.org
       2021-07-17T18:09:21Z
       
       0 likes, 0 repeats
       
       @vrdhn Julia does:julia> 2//3+1//411//12julia> 1//2+1//43//4julia> 1//4+1//41//2
       
 (DIR) Post #A9O78R5pj7tIKkENBA by urusan@fosstodon.org
       2021-07-17T18:24:40Z
       
       0 likes, 0 repeats
       
       @vrdhn Though I can't make any guarantee about the performance of fractions. It's not standardized and you really can't beat the speed of specialized hardware.
       
 (DIR) Post #A9ObeBMAldRDQ3vYIq by Azure@tailswish.industries
       2021-07-18T00:06:35.042911Z
       
       0 likes, 0 repeats
       
       @vrdhn Raku, believe it or not!> 1.5.numerator()3> 1.5.denominator()2Raku is basically a Slovenly Functional language so tends to be a lot more like them than people expect, under the hood.@urusan
       
 (DIR) Post #A9Osk9iRTljlHxmHxY by octesian@refactorcamp.org
       2021-07-18T03:18:06Z
       
       0 likes, 0 repeats
       
       @urusan (double)$0.10 rounded to the nearest cent != (reality).1.1 is not exactly representable in double precision.
       
 (DIR) Post #A9OuRCRdJDCa9t0KUS by octesian@refactorcamp.org
       2021-07-18T03:21:09Z
       
       0 likes, 0 repeats
       
       @urusan or if you want something in pure floating point: . 0.1 * 10.0 != 1.0Don’t be fooled by the fact that when you print out .1 * 10 it prints “1.0”. The print function rounds your numbers.
       
 (DIR) Post #A9OuRCvPWV1NeEw6u8 by urusan@fosstodon.org
       2021-07-18T03:37:06Z
       
       0 likes, 0 repeats
       
       @octesian Looking for the 0.1 thing led to this wonderful URL: https://0.30000000000000004.com/
       
 (DIR) Post #A9PftmkqbBE8j37lSa by octesian@refactorcamp.org
       2021-07-18T12:28:50Z
       
       0 likes, 0 repeats
       
       @urusan my friend, a statistician, was bit in the butt by this in Excel. He put .1 in a cell and smart dragged it down which kept accumulating the not quite .1 value. Then when his coding team converted the spreadsheet into software, they cut and pasted the table with the rounded numbers (as displayed) into the code. They then spent a week trying to figure out why they weren’t getting the same results.