Advertisement
Aslai

Custom floating point

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