在PHP中,是否可以在不损失精度的情况下使用大的无符号int64


Is it possible to use a large unsigned int64 without losing precision in PHP?

我了解Integer大小,PHP_INT_MAX依赖于平台。

在64位系统上,我可以获得:

$large_number = 9223372036854775807

根据我从PHP文档示例3中读到的内容,当整数溢出时,PHP将整数处理为浮点,精度大约为14位小数,即:

Unsigned Int64: 18446744073709551615
PHP will handles as: 1.844674407371E+19

因此,似乎所有的精度都只能达到Signed Int64的最大值。

这真的只是PHP的一个限制,而我对此无能为力吗?

这很有技巧,我向您保证使用GMP会让您的生活更轻松,但使用pack()和一点二进制思维是可能的:

<?php 
$large_number = 9223372036854775807;
$left = 0xffffffff00000000; 
$right = 0x00000000ffffffff; 
$l = ($large_number & $left) >>32; //shift 32 bits left
$r = $large_number & $right; 
$int64_binary_string = pack('NN', $l, $r); 

我还没有测试过,也不会在现实生活中使用它,但它可能接近您想要的。

http://tw1.php.net/manual/en/function.pack.php

如果您需要PHP_INT_MAX/PHP_INT_MIN之外的精度或数字,请学习使用GMP,它可能会一直持续到内存耗尽。。。让你知道你能走多远,

$large_number = gmp_init("9223372036854775807");
$i=0;
while(true){
    echo 'iteration '.$i++.':'.gmp_strval($large_number).'*1337=';
$large_number = gmp_mul($large_number,"1337");
echo gmp_strval($large_number).PHP_EOL;
}

最终将

iteration 1291:63173727399431265977452467325176816266767500735669001788445953704
99100022309199341754638029233101065727095873054512847649411469159231474984853877
29990385564525384931210393372816147935077346316357322846070505282141866990047417
69795035320095201175780336777052639896516690649784147989039497959127394363606555
18277493016490689369408018504673663458745651065704848764945821685549595325229654
78521759046816461228651950877052534907426557036526546565508337234675673499891633
29265311281809541141691613057522094435618917713573494707844587004419303204290366
80410319411622496279245084808349790649184389864091281089934776245296259423173088
37125998364710920001673776690982404095905353172292803413540568804924330209161221
68502039031454119485450113377479892509776976500478875924900269471621353800015849
16768619446056453580306524878177680668058129358555807454509042635315136209751306
28888008462882394248192470687562440408441365704520299664521180552207604024174563
43137016510143518117853956283018500610190006192251441907450531358798897519852285
89712288688300401723956266383086427686519451058576140512867416675873224992592868
63873656820691379608416040082157797343590944870890093034489537997624441231196880
03716995482080107872348544579795198224539076738023147659657987086535844760748293
51680757422559231216506109885022428024013042708325323490543266063675126192858475
51062320509059668456301511665702512575733290996693385011230330439062943182094596
72982868367513131107811463983324141985257032192551001490775273440704964956322520
07994322409745388858643755238449137799970426027598547825636867768578263720009398
06345603047100479826296034929890108340101488966701293667796312958087571285537092
98292308718879824518810679195685709967212889579496467906343837737351387116485926
96065604380646092415099392666166947273008556519323980631398826013377061548412499
37045775535278706790702274483174254245054418225127782273776637425449169726435461
00864900455001093729251741310689643202116980745998974559375404087598011323913589
37378336888032750432647317316783507777959680594838416103235878202519306235270714
07689264877781232001726371838121263807804664374737613209359850417045192588050394
70657700599839677955302104699239419723871651195923433991338871172082351085772713
85795544605616579911291449220540413076513145849439424174121530477862582225947332
71577283620910275735801384726436002832118799836996365693738642178527175171378406
17487708039971384270639342138853231882316669599224158264716457232654635304792216
85595639961619807370286817974879544351592128186367207420223323272766972084744559
66627509594039497325711708953969586289133165339724320993714241576206582692070672
87281148490183467979899908277488360099016745185705207507885725820344193088663031
74742220273886082811546338253396232117540977001317286430939919216858700761871025
04883648220800173612755757031087544792419044177699287860855715222255510614135023
30706372831160632288499262660942154311052431900104315094339186786507006013357031
08125929293885129152264099174616004246743029176792527824811466605161478045492703
27090040582587712800567514734685257659124144431850835544283278381310315791931357
63459289106249506321560095185194943714045276693796155870508190654607382917421646
15486864936613368395909757833185705018554557948762713677856056206953385065593915
49326215023945424937441813782143778143766220175505533500485707438756395764163323
47714668439588417016028256182365660677880890399143415948539281432076160651247693
72982310275084829961404187585100633245654443972233743905144338234758859827413170
88983027723373315156469586730671906768407758289550985343535503818941377020797426
18604249085624012174154963219214543971133251713032811649089587541472009254502083
21938426925234679535003649815691245256828585977342824147515002509080267191887689
93756807224396178461744274960675671607151017304225081498878127594506757910634207
82366257650930768410626608502254524385838019829644847875689142861722171975269086
27152913039908221672006718321592434013558052896236283594560899204934144043552210
8813052796446077685440711695302241857244755302464656726076289075058391*1337=8446
32735330396026118539488137614033486681484835894553911522401035729672982739951992
59510450846561248771271822738836773072631342658924820547496339499714549977043965
30282959394551897891984120249697406451962655622236761656933974621596222296728397
20183102709193795416428153987614058613458087713533262641419642793700816304805168
68985207407486880443429354748473827987325635935798089498320484478359184559360866
27076583226192391712293067578359927580846468827613754693551137122772118377935650
64416866579070402604224929830477624243882128249086083841362204170859705333927752
53506783887636700979595292482900428172427958399610988487824191523745981361850004
22378394358434742762254571913554781639037404921838294896485533928722618505415775
20468015856906162855718175811402571115916602835577500306211903371964419937747843
68698237621235590531937189523891145666785900034163371124374965082326731487376110
98333333092709828260861059469436406514648183983015665803213913077419107406188372
35707395503957353158240382790401778302613604267141259840425062444532997625763710
49295281541865538168765060653162998657037360956425018150966653699907916926437453
64522455898449750483810932923800543871125123028238779261102286096962295954110422
53300041031861800262087455987369484209627287346984244451204684319717267396169213
64686689162749862681054381010309575068563467271336437198517817577032252061277672
60751210970442593137554100625790557600149517970271550344604758277809500736505629
11439273457043778342886520414406889931665405902225381466032093468840906182958490
40067007538064972385604595988992584428764922065891385936525652108407127397334152
77577987012630748507156907484796296338436704249630828087630933181681675714232538
16498780846317942261636333677867775907817110548388045747416843463971305692382555
89878879946652085040124400663361621041802303798851312902275116583020189066763097
91689409840039779256377571669958449000393642378255399242442113685637190833646231
60095781323920529612304032574006289858849152651185411400724689927483641929978732
84494632525395498991320929552989623300263691567683124365569447208054714159350718
63081591475681297110348362690241888609141200075894224902233777226934570198564942
62389139828831041708163976489496312464200707570741034016781184280864313770936734
13966676078625322832980760007005101208004862489022724360915838409882820115703865
87664513792449357865428353820641409325285645926908332041329290558106564944174076
98448004396467710266573872541626995999259033200592474025071939364137062868568245
40734756324139507980786753851729563208385832156894416773034762738098032723080792
44765548714573368685710420592114171685959409873882010592984896309489553137529668
91261773670019374523853883132878624380432154218001861595424734463034850618569271
90374542447907623411522862507612119581666719929400829186215604902943767120983212
02544471505640473874642620655839478699640912521556176910985261615442047526176536
97235141776796603138771014504394692811314927335598670398583505556436746592441767
65771005964615976778954300093716097017729308511008961468237442731938425891977201
43587672002741894902489811053845671227067431958118922138122251574506953505558995
19258472626056397456785349396054603988694509052100709605927409090593842025207354
53313462229692876098074439774957481872935471486966758326990650144914948701503314
13597050267262313782154363746508982901493908456173011366863634889451170372971355
04297785158228883263267504636547471231970192746858267907181665167734883778841765
83973988012795466494399915908765156011779802198725955892514094797030806615012236
41998374589083393493611728331296674043069686059246210768061588107388102747930427
68451858240898452894051575403248691748327785429480763732692852643167679903876653
82998798035791949083798194517073558852275583546403172355538414465285125901769060
33520956224233729387609101357489339640000565938555353265179358602368647929443736
50077755675142991038654325122351616097963840061225439309347683450344473435729237
54729823959690842761271167222679111659279222369969505862293059483051588848405865
434231536619097363136237839395246042763998493353068767

*我所说的"最终"是指在我的笔记本电脑上不到5秒。。

是的,这是PHP的一个限制,除了重新编译PHP解释器之外,你什么都做不了。即便如此,您也只能使用本机系统支持的类型,这些类型通常不会大于64位。正如你所知,你可以使用GMP或BCMath,但这不是你的要求。

在后台,根据您的系统,PHP整数和PHP浮点类型对应于有符号的C整数类型和C浮点类型(PHP总是使用C双精度表示"floats"AFAIK)。这是一个静态关系,在编译后不能更改。由于C类型具有固定的精度,PHP类型当然也有。

浮点中的"溢出"只是一个方便的折衷方案,因此您可以存储非常大的数字,而不是根本不存储。你失去了一些精度是的,但只在有效位。PHP不会自动将数字转换为其他更高精度的浮点格式,因为它没有。