Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » U++ can't handle float to string and back for large numbers
U++ can't handle float to string and back for large numbers [message #47765] Tue, 21 March 2017 09:57 Go to next message
cbpporter is currently offline  cbpporter
Messages: 1265
Registered: September 2007
Senior Veteran
I'm working on a library that tries to do a lot for things, including float work.

I real Maths work, where you do more than 1.0 + 2.0, you often encounter large numbers.

I noticed that U++ can't handle the extremes at all, both by debugging the float values and by using CParser extensively. I looked over CParser code extensively and have not yet found the problem. Most if not all the float to string bits form Core have this problem.

Even something as simple as:

	double d = 1.79769e+302;
	printf("%e\n", d);   // good
	Cout() << d << "\n"; // wrong


Is is wrong at it gets worse as worse as you go up to e303 and up to e308.

I am currently investigating this, since U++ problems with "atof" are also my libraries problems by inheritance.

PS: My official release day was planned for Wednesday, but it will probably be moved back to Friday.

Why do such weird problems only happen before release day? Laughing
Re: U++ can't handle float to string and back for large numbers [message #47766 is a reply to message #47765] Tue, 21 March 2017 10:28 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1265
Registered: September 2007
Senior Veteran
Better test case: 1e308.

After further investigations, it looks like CParser is good. So "atof" is pretty much good I think.

DblStr is to blame, the "ftoa" part. I'm investigating that right now.
Re: U++ can't handle float to string and back for large numbers [message #47767 is a reply to message #47766] Tue, 21 March 2017 10:52 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1265
Registered: September 2007
Senior Veteran
Still under investigation, but:

double normalize(double d, int& exp)
{
	if(IsNull(d) || d == 0)
	{
		exp = Null;
		return d;
	}
	bool sign = (d < 0);
	if(sign) d = -d;
	exp = minmax<int>(ilog10(d), -308, +308); // 8-byte double!
	d /= ipow10(exp);
	if(d >= 10) { d /= 10; exp++; }
	if(d < 1)   { d *= 10; exp--; }
	return sign ? -d : d;
}


Looks like fixes the problem. This, and adding special case to suppress the inherent U++ IsNull mechanic. And some custom work to handle infinite better.
Re: U++ can't handle float to string and back for large numbers [message #47768 is a reply to message #47765] Tue, 21 March 2017 21:35 Go to previous messageGo to next message
mr_ped is currently offline  mr_ped
Messages: 777
Registered: November 2005
Location: Czech Republic - Praha
Veteran

I'm not IEEE expert, but why "exp = minmax<int>(ilog10(d), -308, +308);", I mean why decimal exp, when the native is binary, if I understand the IEEE format correctly. The whole code looks weird, all the computations instead of of working directly with bits, this will be very likely prone to some rounding/cutoffs artefacts. Also doing it directly from bits with decimal conversions only in the last phase would be probably faster, not just more accurate.
Re: U++ can't handle float to string and back for large numbers [message #47769 is a reply to message #47768] Wed, 22 March 2017 07:27 Go to previous messageGo to next message
cbpporter is currently offline  cbpporter
Messages: 1265
Registered: September 2007
Senior Veteran
Yeah, I'm no expert either. And probably 308 is not enough to handle subnormal values.

But it is enough for my needs for now. Without this increase, I can't print a single double and neither can't all of U++, including the debugger.

So the debugger fails, DblStr fails and I need to ftoa the values both in the production code and for debugging.
Re: U++ can't handle float to string and back for large numbers [message #47870 is a reply to message #47767] Sat, 15 April 2017 11:25 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 11051
Registered: November 2005
Ultimate Member
cbpporter wrote on Tue, 21 March 2017 10:52
Still under investigation, but:

double normalize(double d, int& exp)
{
	if(IsNull(d) || d == 0)
	{
		exp = Null;
		return d;
	}
	bool sign = (d < 0);
	if(sign) d = -d;
	exp = minmax<int>(ilog10(d), -308, +308); // 8-byte double!
	d /= ipow10(exp);
	if(d >= 10) { d /= 10; exp++; }
	if(d < 1)   { d *= 10; exp--; }
	return sign ? -d : d;
}


Looks like fixes the problem. This, and adding special case to suppress the inherent U++ IsNull mechanic. And some custom work to handle infinite better.


Thanks, fix applied. This code is ancient, I guess at that time, Tom has not considered handling 'exteremes' so important.
Re: U++ can't handle float to string and back for large numbers [message #47898 is a reply to message #47870] Thu, 20 April 2017 10:44 Go to previous message
cbpporter is currently offline  cbpporter
Messages: 1265
Registered: September 2007
Senior Veteran
Thank you Mirek!

Now I only need to get rid of http://ultimatepp.org/redmine/issues/1650 and I can update U++ again Smile.
Previous Topic: new operator declared twice in MinGW TDM
Next Topic: How to bind parameter to PostCallback with Function, Event object
Goto Forum:
  


Current Time: Sun Jun 25 22:50:26 CEST 2017

Total time taken to generate the page: 0.00774 seconds