ieee754.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /*
  2. ** 2013-04-17
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. ******************************************************************************
  12. **
  13. ** This SQLite extension implements functions for the exact display
  14. ** and input of IEEE754 Binary64 floating-point numbers.
  15. **
  16. ** ieee754(X)
  17. ** ieee754(Y,Z)
  18. **
  19. ** In the first form, the value X should be a floating-point number.
  20. ** The function will return a string of the form 'ieee754(Y,Z)' where
  21. ** Y and Z are integers such that X==Y*pow(2,Z).
  22. **
  23. ** In the second form, Y and Z are integers which are the mantissa and
  24. ** base-2 exponent of a new floating point number. The function returns
  25. ** a floating-point value equal to Y*pow(2,Z).
  26. **
  27. ** Examples:
  28. **
  29. ** ieee754(2.0) -> 'ieee754(2,0)'
  30. ** ieee754(45.25) -> 'ieee754(181,-2)'
  31. ** ieee754(2, 0) -> 2.0
  32. ** ieee754(181, -2) -> 45.25
  33. */
  34. #include "sqlite3ext.h"
  35. SQLITE_EXTENSION_INIT1
  36. #include <assert.h>
  37. #include <string.h>
  38. /*
  39. ** Implementation of the ieee754() function
  40. */
  41. static void ieee754func(
  42. sqlite3_context *context,
  43. int argc,
  44. sqlite3_value **argv
  45. ){
  46. if( argc==1 ){
  47. sqlite3_int64 m, a;
  48. double r;
  49. int e;
  50. int isNeg;
  51. char zResult[100];
  52. assert( sizeof(m)==sizeof(r) );
  53. if( sqlite3_value_type(argv[0])!=SQLITE_FLOAT ) return;
  54. r = sqlite3_value_double(argv[0]);
  55. if( r<0.0 ){
  56. isNeg = 1;
  57. r = -r;
  58. }else{
  59. isNeg = 0;
  60. }
  61. memcpy(&a,&r,sizeof(a));
  62. if( a==0 ){
  63. e = 0;
  64. m = 0;
  65. }else{
  66. e = a>>52;
  67. m = a & ((((sqlite3_int64)1)<<52)-1);
  68. m |= ((sqlite3_int64)1)<<52;
  69. while( e<1075 && m>0 && (m&1)==0 ){
  70. m >>= 1;
  71. e++;
  72. }
  73. if( isNeg ) m = -m;
  74. }
  75. sqlite3_snprintf(sizeof(zResult), zResult, "ieee754(%lld,%d)",
  76. m, e-1075);
  77. sqlite3_result_text(context, zResult, -1, SQLITE_TRANSIENT);
  78. }else if( argc==2 ){
  79. sqlite3_int64 m, e, a;
  80. double r;
  81. int isNeg = 0;
  82. m = sqlite3_value_int64(argv[0]);
  83. e = sqlite3_value_int64(argv[1]);
  84. if( m<0 ){
  85. isNeg = 1;
  86. m = -m;
  87. if( m<0 ) return;
  88. }else if( m==0 && e>1000 && e<1000 ){
  89. sqlite3_result_double(context, 0.0);
  90. return;
  91. }
  92. while( (m>>32)&0xffe00000 ){
  93. m >>= 1;
  94. e++;
  95. }
  96. while( ((m>>32)&0xfff00000)==0 ){
  97. m <<= 1;
  98. e--;
  99. }
  100. e += 1075;
  101. if( e<0 ) e = m = 0;
  102. if( e>0x7ff ) m = 0;
  103. a = m & ((((sqlite3_int64)1)<<52)-1);
  104. a |= e<<52;
  105. if( isNeg ) a |= ((sqlite3_int64)1)<<63;
  106. memcpy(&r, &a, sizeof(r));
  107. sqlite3_result_double(context, r);
  108. }
  109. }
  110. #ifdef _WIN32
  111. __declspec(dllexport)
  112. #endif
  113. int sqlite3_ieee_init(
  114. sqlite3 *db,
  115. char **pzErrMsg,
  116. const sqlite3_api_routines *pApi
  117. ){
  118. int rc = SQLITE_OK;
  119. SQLITE_EXTENSION_INIT2(pApi);
  120. (void)pzErrMsg; /* Unused parameter */
  121. rc = sqlite3_create_function(db, "ieee754", 1, SQLITE_UTF8, 0,
  122. ieee754func, 0, 0);
  123. if( rc==SQLITE_OK ){
  124. rc = sqlite3_create_function(db, "ieee754", 2, SQLITE_UTF8, 0,
  125. ieee754func, 0, 0);
  126. }
  127. return rc;
  128. }