97 lines
3.9 KiB
C
97 lines
3.9 KiB
C
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
||
|
|
||
|
/**
|
||
|
* \file numlib_fltp.h
|
||
|
*
|
||
|
* Lookup table and function to `#include`d in `numlib_ftoa.c`.
|
||
|
*
|
||
|
* \copyright The DoubleFourteen Code Forge (C) All Rights Reserved
|
||
|
* \author Lorenzo Cogotti
|
||
|
*/
|
||
|
|
||
|
#define npowers 87
|
||
|
#define steppowers 8
|
||
|
#define firstpower -348 // 10 ^ -348
|
||
|
|
||
|
#define expmax -32
|
||
|
#define expmin -60
|
||
|
|
||
|
typedef struct {
|
||
|
Uint64 frac;
|
||
|
int exp;
|
||
|
} Fp;
|
||
|
|
||
|
static const Fp powers_ten[] = {
|
||
|
{ 18054884314459144840uLL, -1220 }, { 13451937075301367670uLL, -1193 },
|
||
|
{ 10022474136428063862uLL, -1166 }, { 14934650266808366570uLL, -1140 },
|
||
|
{ 11127181549972568877uLL, -1113 }, { 16580792590934885855uLL, -1087 },
|
||
|
{ 12353653155963782858uLL, -1060 }, { 18408377700990114895uLL, -1034 },
|
||
|
{ 13715310171984221708uLL, -1007 }, { 10218702384817765436uLL, -980 },
|
||
|
{ 15227053142812498563uLL, -954 }, { 11345038669416679861uLL, -927 },
|
||
|
{ 16905424996341287883uLL, -901 }, { 12595523146049147757uLL, -874 },
|
||
|
{ 9384396036005875287uLL, -847 }, { 13983839803942852151uLL, -821 },
|
||
|
{ 10418772551374772303uLL, -794 }, { 15525180923007089351uLL, -768 },
|
||
|
{ 11567161174868858868uLL, -741 }, { 17236413322193710309uLL, -715 },
|
||
|
{ 12842128665889583758uLL, -688 }, { 9568131466127621947uLL, -661 },
|
||
|
{ 14257626930069360058uLL, -635 }, { 10622759856335341974uLL, -608 },
|
||
|
{ 15829145694278690180uLL, -582 }, { 11793632577567316726uLL, -555 },
|
||
|
{ 17573882009934360870uLL, -529 }, { 13093562431584567480uLL, -502 },
|
||
|
{ 9755464219737475723uLL, -475 }, { 14536774485912137811uLL, -449 },
|
||
|
{ 10830740992659433045uLL, -422 }, { 16139061738043178685uLL, -396 },
|
||
|
{ 12024538023802026127uLL, -369 }, { 17917957937422433684uLL, -343 },
|
||
|
{ 13349918974505688015uLL, -316 }, { 9946464728195732843uLL, -289 },
|
||
|
{ 14821387422376473014uLL, -263 }, { 11042794154864902060uLL, -236 },
|
||
|
{ 16455045573212060422uLL, -210 }, { 12259964326927110867uLL, -183 },
|
||
|
{ 18268770466636286478uLL, -157 }, { 13611294676837538539uLL, -130 },
|
||
|
{ 10141204801825835212uLL, -103 }, { 15111572745182864684uLL, -77 },
|
||
|
{ 11258999068426240000uLL, -50 }, { 16777216000000000000uLL, -24 },
|
||
|
{ 12500000000000000000uLL, 3 }, { 9313225746154785156uLL, 30 },
|
||
|
{ 13877787807814456755uLL, 56 }, { 10339757656912845936uLL, 83 },
|
||
|
{ 15407439555097886824uLL, 109 }, { 11479437019748901445uLL, 136 },
|
||
|
{ 17105694144590052135uLL, 162 }, { 12744735289059618216uLL, 189 },
|
||
|
{ 9495567745759798747uLL, 216 }, { 14149498560666738074uLL, 242 },
|
||
|
{ 10542197943230523224uLL, 269 }, { 15709099088952724970uLL, 295 },
|
||
|
{ 11704190886730495818uLL, 322 }, { 17440603504673385349uLL, 348 },
|
||
|
{ 12994262207056124023uLL, 375 }, { 9681479787123295682uLL, 402 },
|
||
|
{ 14426529090290212157uLL, 428 }, { 10748601772107342003uLL, 455 },
|
||
|
{ 16016664761464807395uLL, 481 }, { 11933345169920330789uLL, 508 },
|
||
|
{ 17782069995880619868uLL, 534 }, { 13248674568444952270uLL, 561 },
|
||
|
{ 9871031767461413346uLL, 588 }, { 14708983551653345445uLL, 614 },
|
||
|
{ 10959046745042015199uLL, 641 }, { 16330252207878254650uLL, 667 },
|
||
|
{ 12166986024289022870uLL, 694 }, { 18130221999122236476uLL, 720 },
|
||
|
{ 13508068024458167312uLL, 747 }, { 10064294952495520794uLL, 774 },
|
||
|
{ 14996968138956309548uLL, 800 }, { 11173611982879273257uLL, 827 },
|
||
|
{ 16649979327439178909uLL, 853 }, { 12405201291620119593uLL, 880 },
|
||
|
{ 9242595204427927429uLL, 907 }, { 13772540099066387757uLL, 933 },
|
||
|
{ 10261342003245940623uLL, 960 }, { 15290591125556738113uLL, 986 },
|
||
|
{ 11392378155556871081uLL, 1013 }, { 16975966327722178521uLL, 1039 },
|
||
|
{ 12648080533535911531uLL, 1066 }
|
||
|
};
|
||
|
|
||
|
static Fp find_cachedpow10(int exp, int *k)
|
||
|
{
|
||
|
const double one_log_ten = 0.30102999566398114;
|
||
|
|
||
|
int approx = -(exp + npowers) * one_log_ten;
|
||
|
int idx = (approx - firstpower) / steppowers;
|
||
|
|
||
|
while (TRUE) {
|
||
|
int current = exp + powers_ten[idx].exp + 64;
|
||
|
|
||
|
if (current < expmin) {
|
||
|
idx++;
|
||
|
continue;
|
||
|
}
|
||
|
if (current > expmax) {
|
||
|
idx--;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
*k = (firstpower + idx * steppowers);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return powers_ten[idx];
|
||
|
}
|
||
|
|