voliva / safe-decimal

41 stars 0 forks source link

safe number fractions are really just rational numbers, not a superset #2

Closed programmerjake closed 1 year ago

programmerjake commented 1 year ago

in the article you claim:

This should actually solve both limitations safe numbers have by themselves. The division operation not being safe is gone because we don't need to divide, and we can represent every rational number because this is a superset of them (integers are also safe numbers).

this is incorrect because you're forgetting that integers are rational numbers too.

programmerjake commented 1 year ago

technically safe number fractions are a subset of rational numbers if safe numbers are limited to what you can represent in f64 since f64 can't represent all integers. if safe numbers are not limited to f64, the proper mathematical name is Dyadic Rationals (all rational numbers with a power-of-2 denominator).

voliva commented 1 year ago

this is incorrect because you're forgetting that integers are rational numbers too.

The way I understand rational numbers is any number which can be represented as a fraction of two integers. Rational numbers are a superset of integers, because every integer a can be represented as the rational number a / 1. Based on this I'm not sure what's incorrect from that paragraph.

In there, I'm claiming that by using fractions of safe numbers we can represent every rational number a / b, because if both a and b are integers, then both of them are also safe numbers. Neither a or b when represented in binary have recurring decimals, because they are just integers. So fractions of safe numbers are a superset of rational numbers (fractions of integers)

technically safe number fractions are a subset of rational numbers if safe numbers are limited to what you can represent in f64 since f64 can't represent all integers.

When we drop into the actual implementation then yes, f64 can't represent all the integers, but this is only because it's implemented on f64, which can only represent integers from -2^53 to 2^53. But it can represent more integers than i32 does, or you could use f128 or even an arbitrary-precision decimal library if you do need more range.

if safe numbers are not limited to f64, the proper mathematical name is Dyadic Rationals (all rational numbers with a power-of-2 denominator).

Thank you, I didn't know about this. I gave the name "safe number" just because I didn't know the name of these kind of numbers, and it's exactly what I was looking for.


Something I missed on the article (I just thought about it after writing it) is that this representation of a fraction of decimals is really space inefficient. f64 / f64 is just having (mantissa_a * 2^exp_a) / (mantissa_b * 2^exp_b) which can be simplified down to two numbers getting divided (i.e. a rational number) multiplied by a single exponent.

If we were to represent this into a specific size, say 32 bits, then the disadvantage that it would have against a f32 is that it can represent way less numbers, because there are too many equivalent fractions (e.g. 1/2 == 2/4 == 3/6, etc.). All this redundancy just reduces the space of numbers that can be represented by this format.

programmerjake commented 1 year ago

this is incorrect because you're forgetting that integers are rational numbers too.

The way I understand rational numbers is any number which can be represented as a fraction of two integers. Rational numbers are a superset of integers, because every integer a can be represented as the rational number a / 1. Based on this I'm not sure what's incorrect from that paragraph.

In there, I'm claiming that by using fractions of safe numbers we can represent every rational number a / b, because if both a and b are integers, then both of them are also safe numbers. Neither a or b when represented in binary have recurring decimals, because they are just integers. So fractions of safe numbers are a superset of rational numbers (fractions of integers)

you're forgetting that both a and b are rational numbers (technically dyadic rationals) and any rational a and b where b != 0 means a / b is also rational, including when a and/or b aren't integers. so, no, a / b is not a superset of rational numbers (ignoring infinities and NaNs).

programmerjake commented 1 year ago

Something I missed on the article (I just thought about it after writing it) is that this representation of a fraction of decimals is really space inefficient. f64 / f64 is just having (mantissa_a * 2^exp_a) / (mantissa_b * 2^exp_b) which can be simplified down to two numbers getting divided (i.e. a rational number) multiplied by a single exponent.

that may be true, but using two f64 gives you a major speed advantage since f64 operations are much faster than corresponding separate mantissa, sign, and exponent fields since nearly all cpus have dedicated f64 hardware.

voliva commented 1 year ago

you're forgetting that both a and b are rational numbers (technically dyadic rationals) and any rational a and b where b != 0 means a / b is also rational, including when a and/or b aren't integers. so, no, a / b is not a superset of rational numbers (ignoring infinities and NaNs).

Yes, I see what you mean now, which is also related to my last paragraph

f64 / f64 is just having (mantissa_a 2^exp_a) / (mantissa_b 2^exp_b) which can be simplified down to two numbers getting divided (i.e. a rational number) multiplied by a single exponent.

As you say it's not a superset, but it can still represent all the rational numbers because it's just a different representation of them. From "superset" I meant you can make every rational number (a and b integer) a fraction of decimal numbers, but it's true that it's not actually a superset because there doesn't exist any a/b where a and b are dyadic rationals that can't be represented as regular rational numbers.

I'll try to update the article with these observations. Thank you again!