Un approccio lento ma semplice consiste semplicemente nella stampa di cifre dal più significativo al meno significativo utilizzando la sottrazione. Fondamentalmente è necessaria una funzione per verificare se x >= y
e un altro per il calcolo x -= y
quando questo è il caso. Quindi puoi iniziare a contare quante volte puoi sottrarre 10^38 (e questa sarà la cifra più significativa), quindi quante volte puoi sottrarre 10^37 ... giù a quante volte puoi sottrarre 1.
la seguente è una piena attuazione di questo approccio:
#include <stdio.h>
typedef unsigned ui128[4];
int ge128(ui128 a, ui128 b)
{
int i = 3;
while (i >= 0 && a[i] == b[i])
--i;
return i < 0 ? 1 : a[i] >= b[i];
}
void sub128(ui128 a, ui128 b)
{
int i = 0;
int borrow = 0;
while (i < 4)
{
int next_borrow = (borrow && a[i] <= b[i]) || (!borrow && a[i] < b[i]);
a[i] -= b[i] + borrow;
borrow = next_borrow;
i += 1;
}
}
ui128 deci128[] = {{1u,0u,0u,0u},
{10u,0u,0u,0u},
{100u,0u,0u,0u},
{1000u,0u,0u,0u},
{10000u,0u,0u,0u},
{100000u,0u,0u,0u},
{1000000u,0u,0u,0u},
{10000000u,0u,0u,0u},
{100000000u,0u,0u,0u},
{1000000000u,0u,0u,0u},
{1410065408u,2u,0u,0u},
{1215752192u,23u,0u,0u},
{3567587328u,232u,0u,0u},
{1316134912u,2328u,0u,0u},
{276447232u,23283u,0u,0u},
{2764472320u,232830u,0u,0u},
{1874919424u,2328306u,0u,0u},
{1569325056u,23283064u,0u,0u},
{2808348672u,232830643u,0u,0u},
{2313682944u,2328306436u,0u,0u},
{1661992960u,1808227885u,5u,0u},
{3735027712u,902409669u,54u,0u},
{2990538752u,434162106u,542u,0u},
{4135583744u,46653770u,5421u,0u},
{2701131776u,466537709u,54210u,0u},
{1241513984u,370409800u,542101u,0u},
{3825205248u,3704098002u,5421010u,0u},
{3892314112u,2681241660u,54210108u,0u},
{268435456u,1042612833u,542101086u,0u},
{2684354560u,1836193738u,1126043566u,1u},
{1073741824u,1182068202u,2670501072u,12u},
{2147483648u,3230747430u,935206946u,126u},
{0u,2242703233u,762134875u,1262u},
{0u,952195850u,3326381459u,12621u},
{0u,932023908u,3199043520u,126217u},
{0u,730304488u,1925664130u,1262177u},
{0u,3008077584u,2076772117u,12621774u},
{0u,16004768u,3587851993u,126217744u},
{0u,160047680u,1518781562u,1262177448u}};
void print128(ui128 x)
{
int i = 38;
int z = 0;
while (i >= 0)
{
int c = 0;
while (ge128(x, deci128[i]))
{
c++; sub128(x, deci128[i]);
}
if (i==0 || z || c > 0)
{
z = 1; putchar('0' + c);
}
--i;
}
}
int main(int argc, const char *argv[])
{
ui128 test = { 0x12345678, 0x90abcdef, 0xfedcba90, 0x8765421 };
print128(test);
return 0;
}
Quel numero nel testo problema in decimale diventa
11248221411398543556294285637029484152
e Python è d'accordo questo è il valore corretto (questo naturalmente non lo fa significa che il codice è corretto !!! ;-))
Se non vuoi una libreria bignum, dovrai implementare la divisione lunga da solo. Funziona come l'algoritmo penna-e-carta, solo più facile perché è binario quindi non devi fare così tante ipotesi. Scoprirai che hai bisogno di sottrazione e spostamento. Sei sicuro di non voler usare una libreria di bignum? Stai per implementare uno piuttosto completo te stesso. –
Il decimale è per l'uomo. Tendono a perdere interesse dopo la settima cifra. Qual è esattamente il punto di questo? –
Come deve * essere * stampato sopra? Come "0x1234567890abcdef ..."? Come decimale? – AusCBloke