Something really is off with Single

Chris was having all sorts of issues with floats (System.Single) previously, i’m having the same issues.

See this from the Immediate Window:
?value + (dec / (float)digits)
120890.063
?(dec / (float)digits)
0.06
?dec
60
?digits
1000
?value
120890

How does 120890 + 0.06 = 120890.063?

this is from the breakup of:
float full = value + (dec / (float)digits);

In the watch window, another value:
full = 27946.0215
value = 27946
dec = 224
digits = 10000

Immediate window interrogation:
?(dec / (float)digits)
0.0224
?value
27946
?value + (dec / (float)digits)
27946.0215

For reference, these do work:
value 87242 int
dec 4844 int
digits 10000 int
full 87242.4844 float
(dec / (float)digits) 0.4844 float

	value	105682	int
	dec	961	int
	digits	1000	int
	full	105682.961	float
	(dec / (float)digits)	0.961	float

	value	78429	int
	dec	5547	int
	digits	10000	int
	full	78429.5547	float
	(dec / (float)digits)	0.5547	float

	value	101236	int
	dec	367	int
	digits	1000	int
	full	101236.367	float
	(dec / (float)digits)	0.367	float

these don’t work:
value 98507 int
dec 7266 int
digits 10000 int
full 98507.73 float
(dec / (float)digits) 0.7266 float

	value	54583	int
	dec	5195	int
	digits	10000	int
	full	54583.52	float
	(dec / (float)digits)	0.5195	float

	value	89508	int
	dec	4688	int
	digits	10000	int
	full	89508.47	float
	(dec / (float)digits)	0.4688	float

	value	87882	int
	dec	6094	int
	digits	10000	int
	full	87882.61	float
	(dec / (float)digits)	0.6094	float

This is copy/paste from the watch window.

This could just be an issue with ToString.

I’m writing a string to float conversion class, here is my data.


nums	(Original String)	conv	(As Single)	nums2	(ToString)	nums3	(To String(F4))
[0]	106911.672	[0]	106911.672	[0]	106911.672	[0]	106911.6719
[1]	123085.227	[1]	123085.227	[1]	123085.227	[1]	123085.2266
[2]	9819.23242	[2]	9819.232	[2]	9819.23242	[2]	9819.2324
[3]	82174.0625	[3]	82174.06	[3]	82174.0625	[3]	82174.0625
[4]	103075.414	[4]	103075.414	[4]	103075.414	[4]	103075.4141
[5]	121957.906	[5]	121957.906	[5]	121957.906	[5]	121957.9062
[6]	25476.123	[6]	25476.123	[6]	25476.123	[6]	25476.123
[7]	61569.6953	[7]	61569.6953	[7]	61569.6953	[7]	61569.6953
[8]	3583.10278	[8]	3583.10278	[8]	3583.10278	[8]	3583.1028
[9]	59193.1875	[9]	59193.1875	[9]	59193.1875	[9]	59193.1875
[10]	20065.0273	[10]	20065.0273	[10]	20065.0273	[10]	20065.0273

This is the first 11 rows of 100 test rows.

  • nums is the data as a string.
  • conv is the data stored as a float that is returned back from the converter - the Locals window is converting the value here.
  • nums2 is what i get from a plain old ToString() conversion
  • nums3 is what i get when i specify a decimal length with ToString(“F4”).

Check out array members 2, 3, 4, 5, 8 (nums3 is rounded)

So 50% of this small sample do not read out correctly in some form or another.

I’m not sure if I ever told you, but I had even more issues with my PID controller and floats.

(float)1 + (float)1 would equal 0 or something. I never did verify if it was a bug in ToString() or if it was actually in the data.

Sorry for calling you batshit crazy Chris, i really do believe there is an issue here now.

Btw, i’ve got a string to double converter for the GPS class that is wayyyy faster than the builtin one. My original attempt at going faster than the builtin was 681ms for 200 conversions vs 534ms for the builtin. I’m now at 386.9ms for 200 ops, without compiler optimisations. Compiler optimisations take my code to 313.96ms, double.Parse to 528.28ms. \o/ My version is more than a 1 milisecond faster per conversion.

I found a FastNumberParse class in some netmf uav controller, it came up at over 700ms for the same 200 operations hehe.

It’s really amazing seeing how huge some really basic things can improve performance in NetMF.

Hahaha, told ya!

I had a ton of issues with my PID controller until I dissected it and found out that the floats were all messed up., changing everything to double fixed the issue, at least till I optimize the code.

I remember there was some problem with ToString() long time ago but I thought it was fixed!

Can you please confirm that the numbers are correct (use watch window) but the problem is in ToString()

Then please provide few lines of code and on what device you tried them so we can test them.

Are these just round off errors? Floats are only precise to 7 digits, you seem to have more. The results seem right to me.

Agreed. I think he’s trying to use a float as a decimal type.

I think some people need to understand floating point numbers and how they are implemented.

Ie … if you need total precision you need a 64 bit (double) as there are only a finite decimal places depending on the number ie with 24 bit IEEE float if you number is bigger than 1000 you do not have as much decimal precision as when your number is less than 10.

if you have a 16 bit mantissa and 10 bits make up the actual number there are only 6 bits left for decimal precision. (sounds a lot, but it isnt ) 6 bits will barely give you 2/3 decimal places. where as 12 bits will give you at least 6 / 7 decmal places (obviously depending on the number… recurring numbers are the worst ) 0.5, 0.75, 0.25 and muliples of are the best.

I’m pretty sure a single is 32 bits 1 sign 8 exponent and 23 mantissa.
with the number 103456 you need 17 bits for the number alone leaving 6 for the precision

Singles are good for small numbers but doubles are needed for large numbers and a decent precision…

Hope that helps

Cheers Ian