Live data from Hacker News

0.30000000000000004

0.30000000000000004.com

351–360 of 422 posts

Re: 0.30000000000000004

#351
post #325
post #314

Earlier quoted context omitted.

The trick is that by default rounding happens using banker's rounding. Programming languages use this because this is what CPUs use. When you want to round your way, you need an extra digit and round manually: def tax_f4(amt, rate): tax = round(amt * rate * 1000) return tax // 10 + (tax % 10 > 4)

That works for 10% of $21.15, giving the desired 212. However, for 10.14% of $21.15, it gives 215, but it should be 214. Another example is 3.5% of $60.70, for which it gives 213 but correct is 212.

You're right. My remainder calculation in my code snippet is incorrect. It should've been a floating point remainder instead.

    import math
    
    def tax_f5(amt, rate):
        t = amt * rate * 1000
        return round(t) // 10 + ((math.fmod(t, 10.0) - 5.0) > -1e-7)
But then since there's now an epsilon, it raises the question of how many digits of precision the tax rates typically need. This is indeed a difficult problem.

Re: 0.30000000000000004

#352
post #345
post #196

Earlier quoted context omitted.

> The real lesson is, no matter what base (radix) you use, floating point math is inexact. This is just not true. If you add 1.5 + 4.25 with IEEE754, there is nothing inexact or rounded. That you cannot exactly represent 0.1 in base2 FP is a problem of base2, not FP. You get inexact results with FP math for underflows, overflows, or if you don't have enough precision for the result (or an intermediate result). But th…

A 32 bit floating point number can only have around 4 billion unique values, yet must represent numbers from 10^38, to very small decimals. 99.99999% of numbers in this range cannot be accurately represented in floating point form. Compare that to a 32 bit integer, which can have 4 billion unique values, and supports numbers from 0 to 4 billion. It's a 1:1 mapping.

To be mathematically pedantic, 100% of numbers in that range cannot be accurately represented in floating point form.

Re: 0.30000000000000004

#353

Postgresql figured this out many years ago with their Decimal/Numeric type. It can handle any size number and it performs fractional arithmetic perfectly accurately - how amazingly for the 21st Century! Is comically tragic to me that all of the mainstream programming languages are still so far behind, so primitive that they do not have a native accurate number type that can handle fractions.

> how amazingly for the 21st Century!

Most languages have classes for that, some had them for decades in fact. Hardware floating point numbers target performance and most likely beat any of those classes by orders of magnitude.

Re: 0.30000000000000004

#354

Earlier quoted context omitted.

Decimal numbers are not conceptually any more or less exact than binary numbers. For example, you can't represent 1/3 exactly in decimal, just like you can't represent 1/5 exactly in binary. When handling money, we care about faithfully reproducing the human-centric quirks of decimal numbers , not "being more accurate". There's no reason in principle to regard a system that can't represent 1/3 as being fundamentally…

Money are really best dealt with as integers, any time you'd use a non-integer number, use some fixed multiple that makes it an integer, then divide by the excess factor at the end of the calculation. For instance computing 2.15% yearly interest on a bank account might be done as follows: DaysInYear = 366 InterestRate = 215 DayBalanceSum = 0 for each Day in Year DayBalanceSum += Day.Balance InterestRaw = DayBalanceSu…

This is called fixed-point arithmetic:

https://en.wikipedia.org/wiki/Fixed-point_arithmetic

> In computing, a fixed-point number representation is a real data type for a number that has a fixed number of digits after (and sometimes also before) the radix point.

> A value of a fixed-point data type is essentially an integer that is scaled by an implicit specific factor determined by the type.

Re: 0.30000000000000004

#355

Earlier quoted context omitted.

In a language like Java, all these factors are specified and fully deterministic.

True, that's a good point. I was thinking of C & C++, but you're right, newer languages do a much better job of specifying and controlling this behavior. Wonder if JS does something similar or not.

All major C/C++ compilers implement IEEE754. If you are telling the compiler to disregard it, that is on you.

Re: 0.30000000000000004

#356
post #319
post #20

The big issue here is what you're going to use your numbers for. If you're going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy. If you're handling money, or numbers representing some other real, important concern where accuracy matters, most likely any number you intend to show to the user as a number, f…

> If you're going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy. Um... that really depends. If you have an algorithm that is numerically unstable, these errors will quickly lead to a completely wrong result. Using a different type is not going to fix that, of course, and you need to fix the algorithm.

From your description, I fail to understand how does it depend. You're saying that the algorithm is wrong, and changing the type doesn't help. If the type is not the issue, what difference does it make?

Re: 0.30000000000000004

#357
post #354

Earlier quoted context omitted.

Money are really best dealt with as integers, any time you'd use a non-integer number, use some fixed multiple that makes it an integer, then divide by the excess factor at the end of the calculation. For instance computing 2.15% yearly interest on a bank account might be done as follows: DaysInYear = 366 InterestRate = 215 DayBalanceSum = 0 for each Day in Year DayBalanceSum += Day.Balance InterestRaw = DayBalanceSu…

This is called fixed-point arithmetic: https://en.wikipedia.org/wiki/Fixed-point_arithmetic > In computing, a fixed-point number representation is a real data type for a number that has a fixed number of digits after (and sometimes also before) the radix point. > A value of a fixed-point data type is essentially an integer that is scaled by an implicit specific factor determined by the type.

Yeah, though that notion tends to come with some conceptual shortcomings, like presuming a power of 10 radix. In the above code the radix is implicitly different on leap years, applying such tricks is usually not possible with a fixed point library or language construct.

Re: 0.30000000000000004

#358
post #315

Earlier quoted context omitted.

Hear, hear! It would be great if javascript had any integral type that we could build decimals, rationals, arbitrarily-large integers and so on off. It’s technically doable with doubles if you really know what you’re doing, but it would be so much easier with an integral type.

ES does have an arbitrarily large integer type, BigInt. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

It’s not supported everywhere though, so it’s not like you could use it to actually build a library, you would need to use something that fell back to Doubles anyway.

Re: 0.30000000000000004

#359
post #356
post #319

Earlier quoted context omitted.

> If you're going to do a lot of fast floating point operations for something like graphics or neural networks, these errors are fine. Speed is more important than exact accuracy. Um... that really depends. If you have an algorithm that is numerically unstable, these errors will quickly lead to a completely wrong result. Using a different type is not going to fix that, of course, and you need to fix the algorithm.

From your description, I fail to understand how does it depend. You're saying that the algorithm is wrong, and changing the type doesn't help. If the type is not the issue, what difference does it make?

A single problem can be solved by using many different algorithms.

However, even though algorithm A and B are "correct" they can behave differently when rounding errors are introduced.

For example – if algorithm A uses

https://en.wikipedia.org/wiki/Kahan_summation_algorithm

and B uses naive summation then you can expect the end result of A to be more precise than the end result of B – even though both algorithms are correct.

Re: 0.30000000000000004

#360

Earlier quoted context omitted.

True, that's a good point. I was thinking of C & C++, but you're right, newer languages do a much better job of specifying and controlling this behavior. Wonder if JS does something similar or not.

All major C/C++ compilers implement IEEE754. If you are telling the compiler to disregard it, that is on you.

It's not about IEEE754, it's about the precision that the FP co-processor offers. The results you get are correct per IEEE754, it's just that they may have even less error than required by IEEE754 in some cases. But, this is enough to make the results non-deterministic between different compilation options.

Also, changes applied to the FP co-processor by other processes on the machine could impact your process, regardless of your own compilation settings.

Post reply on HN