/
niceSOFT
/
sqlite
Обзор
Документация
Войти
/
niceSOFT
/
sqlite
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tool/mkfptab.c
238 строк
6 KB
drh
Include the float-point table generator utility in the tools directory.
17 мар 2026, 12:45
17 мар 2026, 12:45
b50ce08
Код
Авторство
О чём код?
/* ** This program generates C code for the tables used to generate powers ** of 10 in the powerOfTen() subroutine in util.c. ** ** The objective of the powerOfTen() subroutine is to provide the most ** significant 96 bits of any power of 10 between -348 and +347. Rather ** than generate a massive 8K table, three much smaller tables are constructed, ** which can then generate the requested power of 10 using a single ** 160-bit multiple. ** ** This program works by internally generating a table of powers of ** 10 accurate to 256 bits each. It then that full-sized, high-accuracy ** table to construct the three smaller tables needed by powerOfTen(). ** ** LIMITATION: ** ** This program uses the __uint128_t datatype, available in gcc/clang. ** It won't build using other compilers. */ #include <stdint.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> typedef unsigned __int128 u128; /* 128-bit unsigned integer */ typedef unsigned long long int u64; /* 64-bit unsigned integer */ /* There is no native 256-bit unsigned integer type, so synthesize one ** using four 64-bit unsigned integers. Must significant first. */ struct u256 { u64 a[4]; /* big-endian */ }; typedef struct u256 u256; /* ** Return a u64 with the N-th bit set. */ #define U64_BIT(N) (((u64)1)<<(N)) /* Multiple *pX by 10, in-place */ static void u256_times_10(u256 *pX){ u64 carry = 0; int i; for(i=3; i>=0; i--){ u128 y = (10 * (u128)pX->a[i]) + carry; pX->a[i] = (u64)y; carry = (u64)(y>>64); } } /* Multiple *pX by 2, in-place. AKA, left-shift */ static void u256_times_2(u256 *pX){ u64 carry = 0; int i; for(i=3; i>=0; i--){ u64 y = pX->a[i]; pX->a[i] = (y<<1) | carry; carry = y>>63; } } /* Divide *pX by 10, in-place */ static void u256_div_10(u256 *pX){ u64 rem = 0; int i; for(i=0; i<4; i++){ u128 acc = (((u128)rem)<<64) | pX->a[i]; pX->a[i] = acc/10; rem = (u64)(acc%10); } } /* Divide *pX by 2, in-place, AKA, right-shift */ static void u256_div_2(u256 *pX){ u64 rem = 0; int i; for(i=0; i<4; i++){ u64 y = pX->a[i]; pX->a[i] = (y>>1) | (rem<<63); rem = y&1; } } /* Note: The main table is a little larger on the low end than the required ** range of -348..+347, since we need the -351 value for the reduced tables. */ #define SCALE_FIRST (-351) /* Least power-of-10 */ #define SCALE_LAST (+347) /* Largest power-of-10 */ #define SCALE_COUNT (SCALE_LAST - SCALE_FIRST + 1) /* Size of main table */ #define SCALE_ZERO (351) int main(int argc, char **argv){ int i, j, iNext; int e; int bRound = 0; int bTruth = 0; const u64 top = ((u64)1)<<63; u256 v; u64 aHi[SCALE_COUNT]; u64 aLo[SCALE_COUNT]; int aE[SCALE_COUNT]; for(i=1; i<argc; i++){ const char *z = argv[i]; if( z[0]=='-' && z[1]=='-' && z[2]!=0 ) z++; if( strcmp(z,"-round")==0 ){ bRound = 1; }else if( strcmp(z,"-truth")==0 ){ bTruth = 1; }else { fprintf(stderr, "unknown option: \"%s\"\n", argv[i]); exit(1); } } /* Generate the master 256-bit power-of-10 table */ v.a[0] = top; v.a[1] = 0; v.a[2] = 0; v.a[3] = 0; for(i=SCALE_ZERO, e=63; i>=0; i--){ aHi[i] = v.a[0]; aLo[i] = v.a[1]; aE[i] = e; u256_div_10(&v); while( v.a[0] < top ){ e++; u256_times_2(&v); } } v.a[0] = 0; v.a[1] = top; v.a[2] = 0; v.a[3] = 0; for(i=SCALE_ZERO+1, e=63; i<SCALE_COUNT; i++){ u256_times_10(&v); while( v.a[0]>0 ){ e--; u256_div_2(&v); } aHi[i] = v.a[1]; aLo[i] = v.a[2]; aE[i] = e; } if( bTruth ){ /* With the --truth flag, also output the aTruth[] table that ** contains 128 bits of every power-of-two in the range */ printf(" /* Powers of ten, accurate to 128 bits each */\n"); printf(" static const struct {u64 hi; u64 lo;} aTruth[] = {\n"); for(i=0; i<SCALE_COUNT; i++){ u64 x = aHi[i]; u64 y = aLo[i]; int e = aE[i]; char *zOp; if( e>0 ){ zOp = "<<"; }else{ e = -e; zOp = ">>"; } printf(" {0x%016llx, 0x%016llx}, /* %2d: 1.0e%+d %s %d */\n", x, y, i, i+SCALE_FIRST, zOp, e); } printf(" };\n"); } /* The aBase[] table contains powers of 10 between 0 and 26. These ** all fit in a single 64-bit integer. */ printf(" static const u64 aBase[] = {\n"); for(i=SCALE_ZERO, j=0; i<SCALE_ZERO+27; i++, j++){ u64 x = aHi[i]; int e = aE[i]; char *zOp; if( e>0 ){ zOp = "<<"; }else{ e = -e; zOp = ">>"; } printf(" UINT64_C(0x%016llx), /* %2d: 1.0e%+d %s %d */\n", x, j, i+SCALE_FIRST, zOp, e); } printf(" };\n"); /* For powers of 10 outside the range [0..26], we have to multiple ** on of the aBase[] entries by a scaling factor to get the true ** power of ten. The scaling factors are all approximates accurate ** to 96 bytes, represented by a 64-bit integer in aScale[] for the ** most significant bits and a 32-bit integer in aScaleLo[] for the ** next 32 bites. ** ** The scale factors are at increments of 27. Except, the entry for 0 ** is replaced by the -1 value as a special case. */ printf(" static const u64 aScale[] = {\n"); for(i=j=0; i<SCALE_COUNT; i=iNext, j++){ const char *zExtra = ""; iNext = i+27; if( i==SCALE_ZERO ){ i--; zExtra = " (special case)"; } u64 x = aHi[i]; int e = aE[i]; char *zOp; if( e>0 ){ zOp = "<<"; }else{ e = -e; zOp = ">>"; } printf(" UINT64_C(0x%016llx), /* %2d: 1.0e%+d %s %d%s */\n", x, j, i+SCALE_FIRST, zOp, e, zExtra); } printf(" };\n"); printf(" static const unsigned int aScaleLo[] = {\n"); for(i=j=0; i<SCALE_COUNT; i=iNext, j++){ const char *zExtra = ""; iNext = i+27; if( i==SCALE_ZERO ){ i--; zExtra = " (special case)"; } u64 x = aLo[i]; int e = aE[i]; char *zOp; if( bRound && (x & U64_BIT(31))!=0 && i!=SCALE_ZERO-1 ) x += U64_BIT(32); if( e>0 ){ zOp = "<<"; }else{ e = -e; zOp = ">>"; } printf(" 0x%08llx, /* %2d: 1.0e%+d %s %d%s */\n", x>>32, j, i+SCALE_FIRST, zOp, e, zExtra); } printf(" };\n"); return 0; }