Advertisement
Aslai

Custom floating point

Jun 11th, 2014
378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //Do note that much greater precision can be achieved if a long double is used instead.
  2. //A long double version of log(), floor(), and pow() would need to be used, though.
  3.  
  4. #include<stdio.h>
  5. #include <math.h>
  6.  
  7. void store_float(FILE* f, double value, int bytes){
  8.     bytes--;
  9.     int is_negative = value >= 0 ? 0 : 1;
  10.     if( value < 0 )
  11.         value = -value;
  12.     int power = floor(bytes*8-log(value)/log(2));
  13.     if( power < -64 || power >= 64 || isinf(value) || isnan(value) )
  14.         power = 63;
  15.  
  16.     value *= pow( 2, power );
  17.     value = floor( value );
  18.     power = (power + 64) & 0xFF;
  19.     power |= is_negative << 7;
  20.     fputc( power, f );
  21.     while( value > 0 && bytes > 0 ){
  22.         fputc( value-floor(value/256)*256, f );
  23.         value = floor( value/256 );
  24.         bytes--;
  25.     }
  26. }
  27.  
  28. double read_float( FILE *f, int bytes ){
  29.     bytes--;
  30.     int power = fgetc( f );
  31.     int is_negative = power & 0x80;
  32.     power &= 0x7F;
  33.     power -= 64;
  34.     double value = 0;
  35.     double multiplier = 1;
  36.     while( bytes-- > 0 ){
  37.         value += (double)fgetc( f ) * multiplier;
  38.         multiplier *= 256;
  39.     }
  40.     if( is_negative )
  41.         value *= -1;
  42.     value /= pow( 2, power );
  43.     if( power == 63 )
  44.         value = pow(2, 1024);
  45.     return value;
  46. }
  47.  
  48. int main(){
  49.     FILE *f = fopen( "test.bin", "w" );
  50.  
  51.     store_float( f, 1080.746356, 8 );
  52.     store_float( f, 1080.746356, 4 );
  53.     store_float( f, 1080.746356, 2 );
  54.     store_float( f, 1234567890123456789.123456789, 8 );
  55.     store_float( f, 1234567890123456789.123456789, 4 );
  56.     store_float( f, 1234567890123456789.123456789, 2 );
  57.     store_float( f, pow(2,1024), 2 );
  58.  
  59.     fclose(f);
  60.  
  61.  
  62.     f = fopen( "test.bin", "r" );
  63.  
  64.     printf("%f\n", read_float( f, 8 ));
  65.     printf("%f\n", read_float( f, 4 ));
  66.     printf("%f\n", read_float( f, 2 ));
  67.     printf("%f\n", read_float( f, 8 ));
  68.     printf("%f\n", read_float( f, 4 ));
  69.     printf("%f\n", read_float( f, 2 ));
  70.     printf("%f\n", read_float( f, 2 ));
  71.  
  72.     fclose(f);
  73.  
  74. }
  75.  
  76.  
  77. /* Output:
  78.  
  79. 1080.746356
  80. 1080.746338
  81. 1080.000000
  82. 1234567890123456800.000000
  83. 1234567802111655900.000000
  84. 1233986297899515900.000000
  85. 1.#INF00
  86.  
  87.  
  88.  
  89. Contents of test.bin (hex dump, separated by stored value):
  90. 6D 90 65 FA 25 E2 17 87
  91. 4D E2 17 87
  92. 3D 87
  93. 3B 08 4C EF A3 87 10 89
  94. 1B 87 10 89
  95. 0B 89
  96. 7F 00
  97. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement