bigdecimal-rs
bigdecimal-rs copied to clipboard
Add `From` impls for primitives
There's currently no way to construct a BigDecimal instance in a way that cannot fail. This is a huge hit to ergonomics. There should be a From impl for all of the numeric types (both integral and floating point)
Good point! num_traits::FromPrimitive was imported, but never implemented. Huge oversight, thanks.
The simplest implementation of from_f32/f64 would be to print to string and then build a decimal from that string; not very efficient but it would be correct for now, then get more efficient after the internals of BigDecimal get more efficient.
The standard library almost had an integer decode method for floating point numbers, which would have been perfect for this usecase, but it's been deprecated.
Note that interpreting decimals from floating point values will return "strange" results, but I think this is to be expected.
python example:
>>> Decimal(12.34)
Decimal('12.339999999999999857891452847979962825775146484375')
rust BigDecimal test:
assert_eq!(BigDecimal::from_str("12.3399999999999999").unwrap(),
BigDecimal::from_f32(12.34).unwrap());
Alright, FromPrimitive is implemented in e46b64af57bd1d54668de6e7f72d79871710b05d
Of course, you meant From<u32>, From<f64>, etc... like every other rust struct, not the num traits. I will get on that next.
Alright, From<u...,i...,f...> are implemented, and instead of going to some arbitrary precision, I'm using the std::f32::DIGITS (== 6) & std::f64::DIGITS ( == 15) constants to indicate precision, so 12.34f32 is equivalent to "12.34000" and 12.34f64 is "12.34000000000000".
The alternative would be to use the decimal's context object (not-yet-implemented) to generate the precision (which must be what python does). I can't think of a reason why you would want to introduce such floating-point errors into numbers, but if anyone.
I will leave this issue open for comments until I publish the updates sometime tonight (EDT).
Further discussion is encouraged on the project's gitter page
I gave this a try, and it looks like the From<f32> and From<f64> impls are incredibly slow. It seems like it's doing string allocation? Seems like it should probably not be doing that.
I was trying to avoid a heap allocation by "printing" to a stack-allocated array like this: https://is.gd/vu1smV, but while it works on playrust, when I run it locally it always crashes, so that's unfortunate.
To avoid the string stuff I'll have to implement some bit manipulation, but that will take some time to ensure it's right.
Alright, I pushed a new implementation of From
As far as I can tell, really small numbers might lose some accuracy, but people using such numbers in floating point representation are already in trouble.
This was merged in 7247fb2. Closing the issue, now.