mod stackvec;
use minimal_lexical::bigint::Bigint;
use minimal_lexical::extended_float::ExtendedFloat;
use minimal_lexical::num::Float;
use minimal_lexical::number::Number;
use minimal_lexical::slow;
use stackvec::vec_from_u32;
fn b<F: Float>(float: F) -> (u64, i32) {
let fp = slow::b(float);
(fp.mant, fp.exp)
}
fn bh<F: Float>(float: F) -> (u64, i32) {
let fp = slow::bh(float);
(fp.mant, fp.exp)
}
#[ test]
fn b_test() {
assert_eq!(b(1 e-45 _f32), (1 , -149 ));
assert_eq!(b(5 e-324 _f64), (1 , -1074 ));
assert_eq!(b(1 e-323 _f64), (2 , -1074 ));
assert_eq!(b(2 e-323 _f64), (4 , -1074 ));
assert_eq!(b(3 e-323 _f64), (6 , -1074 ));
assert_eq!(b(4 e-323 _f64), (8 , -1074 ));
assert_eq!(b(5 e-323 _f64), (10 , -1074 ));
assert_eq!(b(6 e-323 _f64), (12 , -1074 ));
assert_eq!(b(7 e-323 _f64), (14 , -1074 ));
assert_eq!(b(8 e-323 _f64), (16 , -1074 ));
assert_eq!(b(9 e-323 _f64), (18 , -1074 ));
assert_eq!(b(1 _f32), (8388608 , -23 ));
assert_eq!(b(1 _f64), (4503599627370496 , -52 ));
assert_eq!(b(1 e38_f32), (9860761 , 103 ));
assert_eq!(b(1 e308_f64), (5010420900022432 , 971 ));
}
#[ test]
fn bh_test() {
assert_eq!(bh(1 e-45 _f32), (3 , -150 ));
assert_eq!(bh(5 e-324 _f64), (3 , -1075 ));
assert_eq!(bh(1 _f32), (16777217 , -24 ));
assert_eq!(bh(1 _f64), (9007199254740993 , -53 ));
assert_eq!(bh(1 e38_f32), (19721523 , 102 ));
assert_eq!(bh(1 e308_f64), (10020841800044865 , 970 ));
}
#[ test]
fn slow_test() {
// 5e-324, round-down.
let integer = b"2" ;
let fraction = b"4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999" ;
let num = Number {
mantissa: 2470328229206232720 ,
exponent: -342 ,
many_digits: true ,
};
let fp = ExtendedFloat {
mant: 1 << 63 ,
exp: -63 ,
};
let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
assert_eq!(result.mant, 0 );
assert_eq!(result.exp, 0 );
// 5e-324, round-up.
let fraction = b"47032822920623272088284396434110686182529901307162382212792841250337753635104375932649918180817996189898282347722858865463328355177969898199387398005390939063150356595155702263922908583924491051844359318028499365361525003193704576782492193656236698636584807570015857692699037063119282795585513329278343384093519780155312465972635795746227664652728272200563740064854999770965994704540208281662262378573934507363390079677619305775067401763246736009689513405355374585166611342237666786041621596804619144672918403005300575308490487653917113865916462395249126236538818796362393732804238910186723484976682350898633885879256283027559956575244555072551893136908362547791869486679949683240497058210285131854513962138377228261454376934125320985913276672363281251" ;
let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
assert_eq!(result.mant, 1 );
assert_eq!(result.exp, 0 );
// 8.98846567431158e+307
let integer = b"8" ;
let fraction = b"9884656743115805365666807213050294962762414131308158973971342756154045415486693752413698006024096935349884403114202125541629105369684531108613657287705365884742938136589844238179474556051429647415148697857438797685859063890851407391008830874765563025951597582513936655578157348020066364210154316532161708032" ;
let num = Number {
mantissa: 8988465674311580536 ,
exponent: 289 ,
many_digits: true ,
};
let fp = ExtendedFloat {
mant: 9223372036854776832 ,
exp: 2035 ,
};
let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
assert_eq!(result.mant, 0 );
assert_eq!(result.exp, 2046 );
// 8.988465674311582e+307
let fraction = b"98846567431158053656668072130502949627624141313081589739713427561540454154866937524136980060240969353498844031142021255416291053696845311086136572877053658847429381365898442381794745560514296474151486978574387976858590638908514073910088308747655630259515975825139366555781573480200663642101543165321617080321" ;
let result = slow::slow::<f64, _, _>(num.clone(), fp, integer.iter(), fraction.iter());
assert_eq!(result.mant, 1 );
assert_eq!(result.exp, 2046 );
}
#[ test]
fn positive_digit_comp_test() {
// 8.98846567431158e+307
let bigmant = Bigint {
data: vec_from_u32(&[
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 1024 , 2147483648 ,
]),
};
let exponent = 307 + 1 - 308 ;
let result = slow::positive_digit_comp::<f64>(bigmant, exponent);
assert_eq!(result.mant, 0 );
assert_eq!(result.exp, 2046 );
// 8.988465674311582e+307
let bigmant = Bigint {
data: vec_from_u32(&[
1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
0 , 1024 , 2147483648 ,
]),
};
let exponent = 307 + 1 - 308 ;
let result = slow::positive_digit_comp::<f64>(bigmant, exponent);
assert_eq!(result.mant, 1 );
assert_eq!(result.exp, 2046 );
}
#[ test]
fn negative_digit_comp_test() {
// 5e-324, below halfway, round-down to 0.0.
let bigmant = Bigint {
data: vec_from_u32(&[
1727738439 , 330069557 , 3509095598 , 686205316 , 156923684 , 750687444 , 2688855918 ,
28211928 , 1887482096 , 3222998811 , 913348873 , 1652282845 , 1600735541 , 1664240266 ,
84454144 , 1487769792 , 1855966778 , 2832488299 , 507030148 , 1410055467 , 2513359584 ,
3453963205 , 779237894 , 3456088326 , 3671009895 , 3094451696 , 1250165638 , 2682979794 ,
357925323 , 1713890438 , 3271046672 , 3485897285 , 3934710962 , 1813530592 , 199705026 ,
976390839 , 2805488572 , 2194288220 , 2094065006 , 2592523639 , 3798974617 , 586957244 ,
1409218821 , 3442050171 , 3789534764 , 1380190380 , 2055222457 , 3535299831 , 429482276 ,
389342206 , 133558576 , 721875297 , 3013586570 , 540178306 , 2389746866 , 2313334501 ,
422440635 , 1288499129 , 864978311 , 842263325 , 3016323856 , 2282442263 , 1440906063 ,
3931458696 , 3511314276 , 1884879882 , 946366824 , 4260548261 , 1073379659 , 1732329252 ,
3828972211 , 1915607049 , 3665440937 , 1844358779 , 3735281178 , 2646335050 , 1457460927 ,
2940016422 , 1051 ,
]),
};
let fp = ExtendedFloat {
mant: 1 << 63 ,
exp: -63 ,
};
let exponent = -324 + 1 - 755 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 0 );
assert_eq!(result.exp, 0 );
// 5e-324, halfway, round-down to 0.0.
let bigmant = Bigint {
data: vec_from_u32(&[
2084786877 , 507136210 , 2666388819 , 3110242527 , 3178432722 , 541916566 , 208847286 ,
3092404665 , 83491860 , 2893735989 , 3973758097 , 2600107496 , 147629623 , 1754010897 ,
4226332273 , 2587058081 , 942453804 , 88731834 , 1319061990 , 173208747 , 1982493283 ,
3808794987 , 3874839738 , 1854586992 , 3508364323 , 2021729080 , 1899625710 , 2420749567 ,
816401711 , 3059730605 , 1570934109 , 3138812023 , 1756281367 , 3205859133 , 2985201975 ,
1014588672 , 3799556578 , 577719905 , 4052248225 , 3649019757 , 398935965 , 56421532 ,
976366795 , 1876047791 , 3147705595 , 4025764546 , 1097271882 , 1910500779 , 2397021233 ,
1340419138 , 2753207595 , 3067328524 , 2210626776 , 1280440432 , 3940874757 , 4172726578 ,
1035509558 , 1062145421 , 1465448826 , 2990139501 , 1785427751 , 2093931515 , 4055890033 ,
3388365687 , 2245484242 , 3609657408 , 3527114516 , 1013577862 , 2389075196 , 426934091 ,
3237939346 , 1071362463 , 4070999470 , 250952461 , 2280067948 , 1097862995 , 2226250520 ,
221983348 , 1 ,
]),
};
let exponent = -324 + 1 - 752 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 0 );
assert_eq!(result.exp, 0 );
// 5e-324, above halfway, round-up to 5e-324.
let bigmant = Bigint {
data: vec_from_u32(&[
3667999587 , 776394808 , 894084415 , 1037654204 , 1719556155 , 1124198371 , 2088472861 ,
859275578 , 834918607 , 3167556114 , 1082875312 , 231271193 , 1476296236 , 360239786 ,
3608617070 , 100777043 , 834603454 , 887318342 , 305718012 , 1732087473 , 2645063646 ,
3728211506 , 93691724 , 1366000745 , 723904866 , 3037421624 , 1816387920 , 2732659194 ,
3869049819 , 532534979 , 2824439209 , 1323349161 , 382944493 , 1993820262 , 4082215981 ,
1555952134 , 3635827414 , 1482231762 , 1867776587 , 2130459211 , 3989359658 , 564215320 ,
1173733358 , 1580608728 , 1412284882 , 1602939803 , 2382784237 , 1925138608 , 2495375854 ,
519289497 , 1762272177 , 608514174 , 631431287 , 4214469733 , 754041908 , 3072560125 ,
1765160997 , 2031519620 , 1769586374 , 4131591237 , 674408332 , 3759445970 , 1904194670 ,
3818885807 , 980005947 , 1736835717 , 911406800 , 1545844036 , 2415915482 , 4269340915 ,
2314622388 , 2123690045 , 2055289038 , 2509524619 , 1325843000 , 2388695363 , 787668722 ,
2219833485 , 10 ,
]),
};
let exponent = -324 + 1 - 753 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 1 );
assert_eq!(result.exp, 0 );
// 1e-323, below halfway, round-down to 5e-324.
let bigmant = Bigint {
data: vec_from_u32(&[
888248023 , 990208672 , 1937352202 , 2058615950 , 470771052 , 2252062332 , 3771600458 ,
84635785 , 1367478992 , 1079061842 , 2740046621 , 661881239 , 507239328 , 697753503 ,
253362433 , 168342080 , 1272933039 , 4202497602 , 1521090445 , 4230166401 , 3245111456 ,
1771955024 , 2337713684 , 1778330386 , 2423095095 , 693420498 , 3750496916 , 3753972086 ,
1073775970 , 846704018 , 1223205425 , 1867757265 , 3214198296 , 1145624482 , 599115079 ,
2929172517 , 4121498420 , 2287897365 , 1987227723 , 3482603622 , 2806989260 , 1760871734 ,
4227656463 , 1736215921 , 2778669702 , 4140571142 , 1870700075 , 2015964902 , 1288446830 ,
1168026618 , 400675728 , 2165625891 , 450825118 , 1620534920 , 2874273302 , 2645036208 ,
1267321906 , 3865497387 , 2594934933 , 2526789975 , 459036976 , 2552359495 , 27750894 ,
3204441497 , 1944008238 , 1359672352 , 2839100473 , 4191710191 , 3220138979 , 902020460 ,
2896982042 , 1451853853 , 2406388220 , 1238109043 , 2615908943 , 3644037856 , 77415486 ,
230114675 , 3155 ,
]),
};
let fp = ExtendedFloat {
mant: 1 << 63 ,
exp: -62 ,
};
let exponent = -324 + 1 - 755 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 1 );
assert_eq!(result.exp, 0 );
// 1e-323, halfway, round-up to 1e-323.
let bigmant = Bigint {
data: vec_from_u32(&[
1959393335 , 1521408631 , 3704199161 , 740792990 , 945363576 , 1625749700 , 626541858 ,
687279403 , 250475582 , 91273375 , 3331339701 , 3505355194 , 442888870 , 967065395 ,
4089062228 , 3466206949 , 2827361413 , 266195502 , 3957185970 , 519626241 , 1652512553 ,
2836450370 , 3034584624 , 1268793682 , 1935158378 , 1770219946 , 1403909835 , 2967281406 ,
2449205134 , 589257223 , 417835033 , 826501478 , 973876807 , 1027642808 , 365671335 ,
3043766018 , 2808735142 , 1733159717 , 3566810083 , 2357124681 , 1196807897 , 169264596 ,
2929100385 , 1333176077 , 853182194 , 3487359048 , 3291815648 , 1436535041 , 2896096404 ,
4021257415 , 3964655489 , 612050981 , 2336913034 , 3841321297 , 3232689679 , 3928245144 ,
3106528676 , 3186436263 , 101379182 , 380483912 , 1061315959 , 1986827250 , 3577735508 ,
1575162471 , 2441485432 , 2239037633 , 1991408958 , 3040733588 , 2872258292 , 1280802274 ,
1123883446 , 3214087391 , 3623063818 , 752857385 , 2545236548 , 3293588986 , 2383784264 ,
665950045 , 3 ,
]),
};
let exponent = -324 + 1 - 752 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 2 );
assert_eq!(result.exp, 0 );
// 1e-323, above halfway, round-up to 1e-323.
let bigmant = Bigint {
data: vec_from_u32(&[
2414064167 , 2329184426 , 2682253245 , 3112962612 , 863701169 , 3372595114 , 1970451287 ,
2577826735 , 2504755821 , 912733750 , 3248625938 , 693813579 , 133921412 , 1080719359 ,
2235916618 , 302331131 , 2503810362 , 2661955026 , 917154036 , 901295123 , 3640223643 ,
2594699927 , 281075174 , 4098002235 , 2171714598 , 522330280 , 1154196466 , 3903010287 ,
3017214866 , 1597604939 , 4178350331 , 3970047484 , 1148833479 , 1686493490 , 3656713352 ,
372889108 , 2317547651 , 151727992 , 1308362466 , 2096410338 , 3378144383 , 1692645962 ,
3521200074 , 446858888 , 4236854647 , 513852113 , 2853385416 , 1480448529 , 3191160267 ,
1557868492 , 991849235 , 1825542523 , 1894293861 , 4053474607 , 2262125726 , 627745783 ,
1000515697 , 1799591565 , 1013791827 , 3804839120 , 2023224998 , 2688403318 , 1417616716 ,
2866722830 , 2940017843 , 915539855 , 2734220401 , 342564812 , 2952779151 , 4218088154 ,
2648899870 , 2076102840 , 1870899819 , 3233606562 , 3977529001 , 2871118793 , 2363006167 ,
2364533159 , 31 ,
]),
};
let exponent = -324 + 1 - 753 ;
let result = slow::negative_digit_comp::<f64>(bigmant, fp, exponent);
assert_eq!(result.mant, 2 );
assert_eq!(result.exp, 0 );
}
#[ test]
fn parse_mantissa_test() {
let max_digits = f64::MAX_DIGITS;
// Large number of digits.
let integer = b"2" ;
let fraction = b"4703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328124999" ;
let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
let expected = vec_from_u32(&[
1727738439 , 330069557 , 3509095598 , 686205316 , 156923684 , 750687444 , 2688855918 , 28211928 ,
1887482096 , 3222998811 , 913348873 , 1652282845 , 1600735541 , 1664240266 , 84454144 ,
1487769792 , 1855966778 , 2832488299 , 507030148 , 1410055467 , 2513359584 , 3453963205 ,
779237894 , 3456088326 , 3671009895 , 3094451696 , 1250165638 , 2682979794 , 357925323 ,
1713890438 , 3271046672 , 3485897285 , 3934710962 , 1813530592 , 199705026 , 976390839 ,
2805488572 , 2194288220 , 2094065006 , 2592523639 , 3798974617 , 586957244 , 1409218821 ,
3442050171 , 3789534764 , 1380190380 , 2055222457 , 3535299831 , 429482276 , 389342206 ,
133558576 , 721875297 , 3013586570 , 540178306 , 2389746866 , 2313334501 , 422440635 , 1288499129 ,
864978311 , 842263325 , 3016323856 , 2282442263 , 1440906063 , 3931458696 , 3511314276 ,
1884879882 , 946366824 , 4260548261 , 1073379659 , 1732329252 , 3828972211 , 1915607049 ,
3665440937 , 1844358779 , 3735281178 , 2646335050 , 1457460927 , 2940016422 , 1051 ,
]);
assert_eq!(&*bigmant.data, &*expected);
assert_eq!(count, 755 );
// Truncation.
let integer = b"7" ;
let fraction = b"4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375332669816033062329967789262837" ;
let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
let expected = vec_from_u32(&[
983641521 , 2202462645 , 4170685875 , 1591772364 , 529830014 , 803977727 , 126733331 , 1695971390 ,
4089590927 , 1532849076 , 2705586665 , 4046282448 , 4076195232 , 3230469892 , 3059053929 ,
79035789 , 744229654 , 2026438108 , 3570486781 , 2818088662 , 3485839733 , 3653138023 ,
2857937689 , 602717004 , 3689362390 , 283607819 , 1783392475 , 2053068939 , 1888214698 ,
550023429 , 296880187 , 1046779059 , 1285361259 , 84614934 , 1627922685 , 2023868765 , 1987523901 ,
743493573 , 3897769089 , 2210613570 , 2261081349 , 3015057659 , 3949711644 , 3346092916 ,
2433639051 , 36411806 , 1050442 , 269209477 , 2649742673 , 1494221829 , 2763524503 , 2514491481 ,
2325312415 , 1741242814 , 2479923579 , 1098250122 , 2416211509 , 3612906464 , 403420662 ,
3663250314 , 1993722098 , 365907183 , 4270226312 , 3962131185 , 432952495 , 2963635838 ,
2996289227 , 3200289391 , 2753231690 , 2780286109 , 884373163 , 1418533204 , 3382415762 ,
499541562 , 3369625401 , 3421327641 , 3526770155 , 3109983188 , 1157439767 , 734593155 ,
]);
assert_eq!(&*bigmant.data, &*expected);
assert_eq!(count, max_digits + 1 );
// No fraction digits.
let integer = b"74109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375332669816033062329967789262837" ;
let fraction = b"" ;
let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
assert_eq!(&*bigmant.data, &*expected);
assert_eq!(count, max_digits + 1 );
// Multiple of step (check we add our temporary correctly).
let integer = b"7410984687618698162648531893023320585475897039214871466383785237510132609053131277979497545424539885696948470431685765963899850655339096945981621940161728171894510697854671067917687257517734731555330779540854980960845750095811137303474765809687100959097544227100475730780971111893578483867565399878350301522805593404659373979179073872386829939581848166016912201945649993128979841136206248449867871357218035220901702390328579173252022052897402080290685402160661237554998340267130003581248647904138574340187552090159017259254714629617513415977493871857473787096164563890871811984127167305601704549300470526959016576377688490826798697257336652176556794107250876433756084600398490497214911746308553955635418864151316847843631308023759629577398300170898437533266981" ;
let fraction = b"" ;
let (bigmant, count) = slow::parse_mantissa(integer.iter(), fraction.iter(), max_digits);
let expected = vec_from_u32(&[
617018405 , 396211401 , 2130402383 , 3812547827 , 4263683770 , 3918012496 , 1787721490 ,
2493014694 , 435464626 , 3720854431 , 2928509507 , 2677932436 , 369049650 , 3606588290 ,
231237141 , 2231172875 , 3358152367 , 95217925 , 2777810007 , 1016185079 , 596681915 , 2331711780 ,
593487272 , 4212730845 , 339602972 , 4097829793 , 262427536 , 4182115035 , 3414687403 ,
3711518952 , 4168896929 , 483727327 , 1657080031 , 2785588628 , 1009114769 , 482126749 ,
485376744 , 1123705337 , 3225501941 , 2939050108 , 1338451005 , 2104263947 , 3425461126 ,
1834224928 , 4061025704 , 792093815 , 2707019125 , 3610271203 , 4254101529 , 1026215278 ,
4117890107 , 1748110416 , 2535111606 , 80965120 , 3823822115 , 2354910057 , 590658512 ,
2682089507 , 159300272 , 1776569442 , 3382166479 , 3222978591 , 540586210 , 934713382 ,
2014123057 , 1455555790 , 4119131465 , 3685912982 , 3019947291 , 3437891678 , 2660105801 ,
2605860762 , 394373515 , 4177081532 , 1616198650 , 1580399082 , 2017617452 , 3327697130 ,
315505357 ,
]);
assert_eq!(&*bigmant.data, &*expected);
assert_eq!(count, 760 );
}
Messung V0.5 in Prozent C=87 H=100 G=93
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-23)
¤
*© Formatika GbR, Deutschland