Processing float values: decimal output and IEEE 754 bit patterns

Hello folks!

Inspired by this recent discussion:

Why are there individual keywords for different multiples of π

I thought float display and storage deserved a separate topic.

Exploration of float display and storage:

println()              normal readable decimal display
String.format()        formatted decimal display
nf()                   Processing formatted decimal display
System.out.printf()    Java formatted decimal display
floatToIntBits()       actual 32-bit float bit pattern
// Normal Processing println() display:
println("PI         = " + PI);

// Decimal text representations for display purposes only.
// The float value is stored internally as a 32-bit IEEE 754 binary value.
println(String.format("PI         = %.16f", PI));
println("PI         = " + nf(PI, 1, 16));
System.out.printf("PI         = %.16f%n", PI);

// Prints the 32-bit IEEE 754 float bit pattern as hex and binary:
println("PI hex     = " + hex(Float.floatToIntBits(PI), 8));
println("PI binary  = " + binary(Float.floatToIntBits(PI), 32));

References:

Goldberg: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Processing float reference:

Processing nf() reference:

Java Float.toString() and Float.floatToIntBits() reference:

Float.floatToRawIntBits() is left as an exercise for the reader.

:)

Some additional references on comparing floating point:

See example of use here for Processing constants:
Why are there individual keywords for different multiples of π - #7 by glv

Expanded example shows cases that are false:

Code
// The Processing constants are evaluated as double and then cast to float.
// These all evaluated to true

//// PI        = (float)Math.PI;
//println(HALF_PI == PI / 2);

//// THIRD_PI  = (float)(Math.PI / 3.0);
//println(THIRD_PI == PI / 3);

//// QUARTER_PI = (float)(Math.PI / 4.0);
//println(QUARTER_PI == PI / 4);

//// TWO_PI    = (float)(Math.PI * 2.0);
//println(TWO_PI == 2 * PI);

//// TAU       = (float)(Math.PI * 2.0);
//println(TAU == 2 * PI);

// A more generalized example to study:
for(int i=1; i<15; i++)
  {  
  float f1 = (float)(Math.PI / i);     
  //float f = (float)(Math.PI) / i;         
  
  float f2 =  PI/i;      
        
  println("PI/" +i, f1 == f2);
  println(f1);
  println(f2);
  println(nf(f1, 1, 16));
  println(nf(f2, 1, 16));
  println();
  }

Output:

PI/1 true
3.1415927
3.1415927
3.1415927410125732
3.1415927410125732

PI/2 true
1.5707964
1.5707964
1.5707963705062866
1.5707963705062866

PI/3 true
1.0471976
1.0471976
1.0471975803375244
1.0471975803375244

PI/4 true
0.7853982
0.7853982
0.7853981852531433
0.7853981852531433

PI/5 true
0.62831855
0.62831855
0.6283185482025146
0.6283185482025146

PI/6 true
0.5235988
0.5235988
0.5235987901687622
0.5235987901687622

PI/7 true
0.44879895
0.44879895
0.4487989544868469
0.4487989544868469

PI/8 true
0.3926991
0.3926991
0.3926990926265717
0.3926990926265717

PI/9 false
0.34906584
0.34906587
0.3490658402442932
0.3490658700466156

PI/10 true
0.31415927
0.31415927
0.3141592741012573
0.3141592741012573

PI/11 false
0.28559932
0.28559935
0.2855993211269379
0.2855993509292603

PI/12 true
0.2617994
0.2617994
0.2617993950843811
0.2617993950843811

PI/13 false
0.24166097
0.24166098
0.2416609674692154
0.2416609823703766

PI/14 true
0.22439948
0.22439948
0.2243994772434235
0.2243994772434235

:)