Processing 4 Java Bug bad printing of a number

Have got a bug - look like its JAVA that freaking.

float vDATA = {{45576469, 84.847, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, }, // tous 253
{45576469, 84.861, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86, }, // tous 254
{45576469, 84.875, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86, }, // tous 255
{45576469, 84.889, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, }, // tous 256
{45576469, 84.903, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95, }} ; // tous 257

for(int i = 0; i< vDATA.length ; i++) {

println( (int)vDATA[i][0] + ", " + vDATA[i][1] + ", ") ;

}
/*
Result
45576468, 84.847, // should be 45576469 ???
45576468, 84.861,
45576468, 84.875,
45576468, 84.889,
45576468, 84.903,
*/

1 Like

(post deleted by author)

1 Like

Yes but why

printing 45576469 , 84.847, give 45576468 , 84.847,

(post deleted by author)

Ok Find the solution but I don’t know why Java react like that :slight_smile:

float [][] vDATA = {{ 45576469 , 84.847, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },     //  tous  253
{ 45576469 , 84.861, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 },     //  tous  254
{ 45576469 , 84.875, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 },     //  tous  255
{ 45576469 , 84.889, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },     //  tous  256
{ 45576469 , 84.903, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 }} ;     //  tous  257

for(int i = 0; i< vDATA.length ; i++)  {
  
  println(  (int)vDATA[i][0] + ", " +  vDATA[i][1] + ", ") ;   

  

}

/*
45576468, 84.847,     BUG 45576468  --> 69
45576468, 84.861, 
45576468, 84.875, 
45576468, 84.889, 
45576468, 84.903, 
*/

println() ;

int [][] vDATA2 = {{ 45576469 , 84847, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },     //  tous  253
{ 45576469 , 84861, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 },     //  tous  254
{ 45576469 , 84875, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 },     //  tous  255
{ 45576469 , 84889, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },     //  tous  256
{ 45576469 , 84903, 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 }} ;     //  tous  257

for(int i = 0; i< vDATA2.length ; i++)  {
  
  println(  vDATA2[i][0] + ", " +  vDATA2[i][1]/1000.0  + ", ") ;   

  

}
/*
45576469, 84.847,     // Good print
45576469, 84.861, 
45576469, 84.875, 
45576469, 84.889, 
45576469, 84.903,
*/

Floating-point numbers are stored in a format similar to numbers in scientific notation with an exponent and a mantissa (the significant digits) all packed into either 32 bits of space for a float or 64 bits for a double.

For a float data type, the mantissa stores 23 bits with an implied leading 1 as a 24th bit. That means a float can only store integer values up to 2^24 or 16777216 before they start losing precision. The other 9 bits in the float store the sign and 8 bits for the exponent.

If you try to assign an integer with a value larger than 2^24 into a float, the lowest binary digits simply won’t be stored, effectively be zero-ing them out. Printing isn’t the problem. Storing a number with enough precision is the problem.

A double stores 53 bits in its mantissa, so it can easily store all the values of a 32-bit integer without loss. Or, as you do, you can store the numbers as integers as long as they are smaller than 2^31 or 2147483648 (leaving the 32nd bit for the sign).

2 Likes

Given the index[1] is the only float primitive datatype, you can store it separately:
final float[] fDATA = { 84.847, 84.861, 84.875, 84.889, 84.903 };

Also, the index[0] is the only big int value. For the other indices, a byte is just enough:

final int[] iDATA = { 45576469, 45576469, 45576469, 45576469, 45576469 };

final float[] fDATA = { 84.847, 84.861, 84.875, 84.889, 84.903 };

final byte[][] vDATA = {
  { 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },      // tous 253
  { 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 }, // tous 254
  { 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 87, 88, 89, 91, 92, 93, 94, 95, 96, -86 }, // tous 255
  { 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 },      // tous 256
  { 45, 57, 64, 69, 73, 76, 79, 81, 83, 85, 86, 87, 88, 89, 91, 92, 93, 94, 95 }       // tous 257
};

for (int i = 0; i < vDATA.length; i++)
  println(i + ":", iDATA[i] + ",", fDATA[i] + ",", join(str(vDATA[i]), ", "));