digitalmars.D.learn - Stop to! rounding?
- Josh (4/4) Jul 02 2013 writeln(to!double("151.42499")); //prints 151.425
- Jonathan M Davis (8/11) Jul 02 2013 No. double can't hold the value 151.42499. There are _tons_ of values th...
- Josh (4/17) Jul 02 2013 Is there any way I would be able to hold that number then?
- Jonathan M Davis (9/29) Jul 02 2013 Without rounding? You'd need fixed point math rather than floating point...
- Josh (5/41) Jul 02 2013 Jonathan, do you know of any fixed point D library? If not, would
- Jonathan M Davis (8/10) Jul 02 2013 I am unaware of one, and I don't really know why anyone would really wan...
- monarch_dodra (19/31) Jul 03 2013 Said the man who then went on to state "I really don't like
- Maxim Fomin (2/4) Jul 03 2013 Really? What kind of apps?
- monarch_dodra (7/13) Jul 03 2013 I meant "apps" as in short for program, not phone "apps". It's
- Jay Norwood (18/26) Jul 03 2013 This arbitrary precision c++ arithmetic package has a flexible
- bearophile (5/6) Jul 03 2013 One way to do that is with a simple rationals library,
- cal (7/20) Jul 02 2013 void main()
- Jonathan M Davis (6/32) Jul 02 2013 That's true because _both_ of the floating point values there get rounde...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (14/25) Jul 02 2013 The value that can be stored is not 151.42499, nor 151.425.
- H. S. Teoh (11/19) Jul 02 2013 I wouldn't write it like that; IMO it's better to write:
- Timon Gehr (4/21) Jul 02 2013 double.dig gets you the number of significant digits in total. The
- Marco Leise (6/29) Jul 03 2013 *f ? I didn't know that you can format the format string like
- H. S. Teoh (15/44) Jul 03 2013 [...]
- Jonathan M Davis (7/43) Jul 02 2013 Ah. You learn new things every day. Well, I stand corrected. I was half=
- cal (7/44) Jul 02 2013 import std.stdio;
- cal (4/8) Jul 02 2013 The rounding is probably just a stdio default floating point
writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding? Thanks, Josh
Jul 02 2013
On Wednesday, July 03, 2013 06:23:12 Josh wrote:writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 06:23:12 Josh wrote:Is there any way I would be able to hold that number then? Thanks, Joshwriteln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, July 03, 2013 06:44:33 Josh wrote:On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:Without rounding? You'd need fixed point math rather than floating point math. There is nothing built into the language to support that (or into any C-based language of which I'm aware). I believe that C libraries exist which provide it though. http://en.wikipedia.org/wiki/Fixed-point_arithmetic Most people just use floating point though, since in most cases, you really don't need fixed point. - Jonathan M DavisOn Wednesday, July 03, 2013 06:23:12 Josh wrote:Is there any way I would be able to hold that number then?writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, 3 July 2013 at 04:51:06 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 06:44:33 Josh wrote:Jonathan, do you know of any fixed point D library? If not, would it be worth me making one for phobos? Thanks, JoshOn Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:Without rounding? You'd need fixed point math rather than floating point math. There is nothing built into the language to support that (or into any C-based language of which I'm aware). I believe that C libraries exist which provide it though. http://en.wikipedia.org/wiki/Fixed-point_arithmetic Most people just use floating point though, since in most cases, you really don't need fixed point. - Jonathan M DavisOn Wednesday, July 03, 2013 06:23:12 Josh wrote:Is there any way I would be able to hold that number then?writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, July 03, 2013 08:11:50 Josh wrote:Jonathan, do you know of any fixed point D library? If not, would it be worth me making one for phobos?I am unaware of one, and I don't really know why anyone would really want fixed point rather than floating point, so I don't know what use cases it would be valid for or how much interest there would really be in adding something like that to Phobos. However, there's probably a decent chance of something like that making it into Phobos if someone came up with a solid implemantation for it. - Jonathan M Davis
Jul 02 2013
On Wednesday, 3 July 2013 at 06:18:28 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 08:11:50 Josh wrote:Said the man who then went on to state "I really don't like dealing with floating point numbers." ;) That said, fixed point types, and/or "decimal floating point types" are both very important features to specific domains: Just the same way certain fields (gaming) have weird requirements, so do certain other fields. My brother in law writes financial apps, and in that field, using floating points type is *legally* forbidden. My wife writes the embeded code for a machine here company manufactures. Ditto: no floating point types allowed. She's told me that their code is *riddled* with things like "mv = v * 1000": because they don't have a way to handle fractinal numbers. Long story short, I think both would be a great addition to phobos/D. I'd personally really want to play with decimal floats: They are slower, less precise and have less range, but are more "exact" in base 10 than traditional floats. And when printed in Base 10, are *always* exact.Jonathan, do you know of any fixed point D library? If not, would it be worth me making one for phobos?I am unaware of one, and I don't really know why anyone would really want fixed point rather than floating point, so I don't know what use cases it would be valid for or how much interest there would really be in adding something like that to Phobos. - Jonathan M Davis
Jul 03 2013
On Wednesday, 3 July 2013 at 08:23:40 UTC, monarch_dodra wrote:My brother in law writes financial apps, and in that field, using floating points type is *legally* forbidden.Really? What kind of apps?
Jul 03 2013
On Wednesday, 3 July 2013 at 08:27:52 UTC, Maxim Fomin wrote:On Wednesday, 3 July 2013 at 08:23:40 UTC, monarch_dodra wrote:I meant "apps" as in short for program, not phone "apps". It's complicated to explain, but in a word, He basically programs distributed servers to do stock trading. I'm not allowed to talk about it much, especially on some random board :( About the whole "legally forbidden" thing: I'm not sure it is the entire "financial" field, but definitly in the accounting field.My brother in law writes financial apps, and in that field, using floating points type is *legally* forbidden.Really? What kind of apps?
Jul 03 2013
On Wednesday, 3 July 2013 at 08:23:40 UTC, monarch_dodra wrote:On Wednesday, 3 July 2013 at 06:18:28 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 08:11:50 Josh wrote:Long story short, I think both would be a great addition to phobos/D. I'd personally really want to play with decimal floats: They are slower, less precise and have less range, but are more "exact" in base 10 than traditional floats. And when printed in Base 10, are *always* exact.This arbitrary precision c++ arithmetic package has a flexible feature of allowing selection of the internal base. The default base 10. Much of it is implemented in c++ templates. I put a small excerpt below. http://www.hvks.com/Numerical/arbitrary_precision.html /// Description: /// Add operator for float_precision + <any other type> /// no const on the lhs parameter to prevent ambigous overload /// template <class _Ty> inline float_precision operator+( float_precision& lhs, const _Ty& rhs ) { float_precision c(rhs); if( lhs.precision() > c.precision() ) c.precision( lhs.precision() ); return c += lhs; }
Jul 03 2013
Josh:Is there any way I would be able to hold that number then?One way to do that is with a simple rationals library, represented as pairs of bigints. Bye, bearophile
Jul 03 2013
On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 06:23:12 Josh wrote:void main() { double d = 151.42499; assert(d == 151.42499); } The rounding occurs in writeln surely.writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, July 03, 2013 07:04:47 cal wrote:On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:That's true because _both_ of the floating point values there get rounded to 151.425, and 151.425 is equal to 151.425. writeln is not doing anything wrong. I highly suggest that you read this: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html - Jonathan M DavisOn Wednesday, July 03, 2013 06:23:12 Josh wrote:void main() { double d = 151.42499; assert(d == 151.42499); } The rounding occurs in writeln surely.writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On 07/02/2013 10:09 PM, Jonathan M Davis wrote:On Wednesday, July 03, 2013 07:04:47 cal wrote:rounded tovoid main() { double d = 151.42499; assert(d == 151.42499); } The rounding occurs in writeln surely.That's true because _both_ of the floating point values there get151.425,The value that can be stored is not 151.42499, nor 151.425. import std.stdio; import std.conv; void main() { auto a = to!double("151.42499"); writefln("%.60f", a); } Prints: 151.424990000000008194547262974083423614501953125000000000000000writeln is not doing anything wrong.True. It is using its default floating point precision, 6. Ali
Jul 02 2013
On Tue, Jul 02, 2013 at 10:14:33PM -0700, Ali Çehreli wrote: [...]import std.stdio; import std.conv; void main() { auto a = to!double("151.42499"); writefln("%.60f", a); }I wouldn't write it like that; IMO it's better to write: writefln("%.*f", double.dig, a); So that you don't give the wrong impression that there are more digits than are actually there. Using double.dig also lets you see all the digits that *are* there, not a rounded value, that the OP was complaining about. T -- The easy way is the wrong way, and the hard way is the stupid way. Pick one.
Jul 02 2013
On 07/03/2013 07:21 AM, H. S. Teoh wrote:On Tue, Jul 02, 2013 at 10:14:33PM -0700, Ali Çehreli wrote: [...]double.dig gets you the number of significant digits in total. The number of significant digits after the decimal point is dependent on the exponent.import std.stdio; import std.conv; void main() { auto a = to!double("151.42499"); writefln("%.60f", a); }I wouldn't write it like that; IMO it's better to write: writefln("%.*f", double.dig, a); So that you don't give the wrong impression that there are more digits than are actually there. Using double.dig also lets you see all the digits that *are* there, not a rounded value, that the OP was complaining about. ...
Jul 02 2013
Am Tue, 2 Jul 2013 22:21:52 -0700 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:On Tue, Jul 02, 2013 at 10:14:33PM -0700, Ali =C3=87ehreli wrote: [...]*f ? I didn't know that you can format the format string like that. Thanks for the tip. --=20 Marcoimport std.stdio; import std.conv; =20 void main() { auto a =3D to!double("151.42499"); writefln("%.60f", a); }=20 I wouldn't write it like that; IMO it's better to write: =20 writefln("%.*f", double.dig, a); =20 So that you don't give the wrong impression that there are more digits than are actually there. Using double.dig also lets you see all the digits that *are* there, not a rounded value, that the OP was complaining about. =20 =20 T =20
Jul 03 2013
On Wed, Jul 03, 2013 at 07:56:28PM +0200, Marco Leise wrote:Am Tue, 2 Jul 2013 22:21:52 -0700 schrieb "H. S. Teoh" <hsteoh quickfur.ath.cx>:[...] Basically, it's a wildcard precision. Usually you'd write %.5f for 5 digits following the decimal point, for example, but that requires hardcoding the integer literal into the format string. In some cases you need it to be variable, so '*' was introduced as a stand-in for the next item in the argument list. So writefln("%.*f", 5, a) is equivalent to writefln("%.5f", a). The wildcard * can also be used in the field-width, so writefln("%*.*f", 5, 2, 1) is equivalent to writefln("%5.2f", 1). This isn't D's innovation, BTW, the * width/precision specifier is defined in the same way in C's printf(). T -- He who does not appreciate the beauty of language is not worthy to bemoan its flaws.On Tue, Jul 02, 2013 at 10:14:33PM -0700, Ali Çehreli wrote: [...]*f ? I didn't know that you can format the format string like that. Thanks for the tip.import std.stdio; import std.conv; void main() { auto a = to!double("151.42499"); writefln("%.60f", a); }I wouldn't write it like that; IMO it's better to write: writefln("%.*f", double.dig, a); So that you don't give the wrong impression that there are more digits than are actually there. Using double.dig also lets you see all the digits that *are* there, not a rounded value, that the OP was complaining about. T
Jul 03 2013
On Tuesday, July 02, 2013 22:14:33 Ali =C3=87ehreli wrote:On 07/02/2013 10:09 PM, Jonathan M Davis wrote: > On Wednesday, July 03, 2013 07:04:47 cal wrote: >> void main() >> { >>=20 >> double d =3D 151.42499; >> assert(d =3D=3D 151.42499); >>=20 >> } >>=20 >> The rounding occurs in writeln surely. >=20 > That's true because _both_ of the floating point values there get =20 rounded to =20 > 151.425, =20 The value that can be stored is not 151.42499, nor 151.425. =20 import std.stdio; import std.conv; =20 void main() { auto a =3D to!double("151.42499"); writefln("%.60f", a); } =20 Prints: =20 151.424990000000008194547262974083423614501953125000000000000000 =20 > writeln is not doing anything wrong. =20 True. It is using its default floating point precision, 6.Ah. You learn new things every day. Well, I stand corrected. I was half= right.=20 It isn't 151.42499, but writeln _is_ rounding. I really don't like deal= ing=20 with floating point numbers. - Jonathan M Davis
Jul 02 2013
On Wednesday, 3 July 2013 at 05:10:03 UTC, Jonathan M Davis wrote:On Wednesday, July 03, 2013 07:04:47 cal wrote:import std.stdio; void main() { double d = 151.42499; writefln("%.10f", d); }On Wednesday, 3 July 2013 at 04:32:15 UTC, Jonathan M Davis wrote:That's true because _both_ of the floating point values there get rounded to 151.425, and 151.425 is equal to 151.425. writeln is not doing anything wrong. I highly suggest that you read this: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html - Jonathan M DavisOn Wednesday, July 03, 2013 06:23:12 Josh wrote:void main() { double d = 151.42499; assert(d == 151.42499); } The rounding occurs in writeln surely.writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding?No. double can't hold the value 151.42499. There are _tons_ of values that it can't hold exactly. The same goes for float and real. Floating point values are rounded all the time. Note that double d = 151.42499; writeln(d); prints exactly the same thing as your example. - Jonathan M Davis
Jul 02 2013
On Wednesday, 3 July 2013 at 04:23:17 UTC, Josh wrote:writeln(to!double("151.42499")); //prints 151.425 Is there any way to stop this rounding? Thanks, JoshThe rounding is probably just a stdio default floating point format, ie: writefln("%.10f", to!double("151.42499")); // 151.4249900000
Jul 02 2013