Kaydet (Commit) 284d9276 authored tarafından Christian Heimes's avatar Christian Heimes

Backport of r59456:59458 from py3k to trunk

Issue #1580: New free format floating point representation based on "Floating-Point Printer Sample Code", by Robert G. Burger. For example repr(11./5) now returns '2.2' instead of '2.2000000000000002'.

Thanks to noam for the patch! I had to modify doubledigits.c slightly to support X64 and IA64 machines on Windows. I also added the new file to the three project files.
üst 8c3d0f78
......@@ -86,6 +86,10 @@ PyAPI_FUNC(void) PyFloat_AsString(char*, PyFloatObject *v);
PyAPI_FUNC(int) _PyFloat_Pack4(double x, unsigned char *p, int le);
PyAPI_FUNC(int) _PyFloat_Pack8(double x, unsigned char *p, int le);
/* Used to get the important decimal digits of a double */
PyAPI_FUNC(int) _PyFloat_Digits(char *buf, double v, int *signum);
PyAPI_FUNC(void) _PyFloat_DigitsInit(void);
/* The unpack routines read 4 or 8 bytes, starting at p. le is a bool
* argument, true if the string is in little-endian format (exponent
* last, at p+3 or p+7), false if big-endian (exponent first, at p).
......
# These numbers are used to test floating point binary-to-decimal conversion.
# They are based on the TCL test suite (tests/expr.test), which is based on
# test data from:
# Brigitte Verdonk, Annie Cuyt, Dennis Verschaeren, A precision and range
# independent tool for testing floating-point arithmetic II: Conversions,
# ACM Transactions on Mathematical Software 27:2 (March 2001), pp. 119-140.
0E0
-0E0
1E0
15E-1
125E-2
1125E-3
10625E-4
103125E-5
1015625E-6
10078125E-7
100390625E-8
1001953125E-9
10009765625E-10
100048828125E-11
1000244140625E-12
10001220703125E-13
100006103515625E-14
1000030517578125E-15
10000152587890625E-16
+8E153
-1E153
+9E306
-2E153
+7E-304
-3E-49
+7E-303
-6E-49
+9E43
-9E44
+8E303
-1E303
+7E-287
-2E-204
+2E-205
-9E-47
+34E195
-68E195
+85E194
-67E97
+93E-234
-19E-87
+38E-87
-38E-88
-69E220
+18E43
-36E43
+61E-99
-43E-92
+86E-92
-51E-74
+283E85
-566E85
+589E187
-839E143
-744E-234
+930E-235
-186E-234
+604E175
-302E175
+755E174
-151E175
+662E-213
-408E-74
+510E-75
+6782E55
-2309E92
+7963E34
-3391E55
+7903E-96
-7611E-226
+4907E-196
-5547E-311
+5311E241
-5311E243
+5311E242
+9269E-45
-8559E-289
+8699E-276
-8085E-64
+74819E201
-82081E41
+51881E37
-55061E157
+77402E-215
-33891E-92
+38701E-215
-82139E-76
+75859E25
+89509E140
-57533E287
+46073E-32
-92146E-32
+83771E-74
-34796E-276
+584169E229
+164162E41
-328324E41
+209901E-11
-419802E-11
+940189E-112
-892771E-213
+757803E120
-252601E120
+252601E121
-505202E120
+970811E-264
-654839E-60
+289767E-178
-579534E-178
-8823691E130
+9346704E229
-1168338E229
-6063369E-136
+3865421E-225
-5783893E-127
+2572231E223
-5144462E223
+1817623E109
+6431543E-97
-5444097E-21
+8076999E-121
-9997649E-270
+50609263E157
+70589528E130
-88236910E129
+87575437E-310
-23135572E-127
+85900881E177
-84863171E113
+68761586E232
-50464069E286
+27869147E-248
-55738294E-248
+70176353E-53
-80555086E-32
-491080654E121
+526250918E287
-245540327E121
-175150874E-310
+350301748E-310
-437877185E-311
+458117166E52
-916234332E52
+229058583E52
-525789935E98
+282926897E-227
-565853794E-227
+667284113E-240
-971212611E-126
+9981396317E-182
-5035231965E-156
+8336960483E-153
-8056371144E-155
+6418488827E79
-3981006983E252
+7962013966E252
-4713898551E261
+8715380633E-58
-9078555839E-109
+9712126110E-127
+42333842451E201
-84667684902E201
+23792120709E-315
-78564021519E-227
+71812054883E-188
-30311163631E-116
+71803914657E292
+36314223356E-109
+18157111678E-109
-45392779195E-110
+778380362293E218
-685763015669E280
+952918668151E70
-548357443505E32
+384865004907E-285
-769730009814E-285
+697015418417E-93
-915654049301E-28
+178548656339E169
-742522891517E259
+742522891517E258
-357097312678E169
-3113521449172E218
+3891901811465E217
-1556760724586E218
+9997878507563E-195
-7247563029154E-319
+3623781514577E-319
-3092446298323E-200
+6363857920591E145
-8233559360849E94
+2689845954547E49
-5379691909094E49
+5560322501926E-301
-7812878489261E-179
+8439398533053E-256
-2780161250963E-301
-87605699161665E155
-17521139832333E156
-88218101363513E-170
+38639244311627E-115
+35593959807306E261
-53390939710959E260
+71187919614612E261
-88984899518265E260
+77003665618895E-73
-15400733123779E-72
+61602932495116E-72
-30801466247558E-72
+834735494917063E-300
-589795149206434E-151
+475603213226859E-42
-294897574603217E-151
+850813008001913E93
-203449172043339E185
+406898344086678E185
-813796688173356E185
+6045338514609393E244
-5145963778954906E142
+2572981889477453E142
-6965949469487146E74
+6182410494241627E-119
-8510309498186985E-277
+6647704637273331E-212
-2215901545757777E-212
+3771476185376383E276
-3729901848043846E212
+3771476185376383E277
-9977830465649166E119
+8439928496349319E-142
-8204230082070882E-59
+8853686434843997E-244
-5553274272288559E-104
+36149023611096162E144
-36149023611096162E147
+18074511805548081E146
-18074511805548081E147
+97338774138954421E-290
-88133809804950961E-308
+94080055902682397E-243
-24691002732654881E-115
+52306490527514614E49
-26153245263757307E49
+55188692254193604E165
-68985865317742005E164
+27176258005319167E-261
-73169230107256116E-248
+91461537634070145E-249
-54352516010638334E-261
+586144289638535878E280
-601117006785295431E245
+293072144819267939E280
-953184713238516652E272
+902042358290366539E-281
-557035730189854663E-294
+902042358290366539E-280
-354944100507554393E-238
+272104041512242479E199
-816312124536727437E199
+544208083024484958E199
-792644927852378159E78
-679406450132979175E-263
+543525160106383340E-262
+7400253695682920196E215
-1850063423920730049E215
+3700126847841460098E215
-9250317119603650245E214
+8396094300569779681E-252
-3507665085003296281E-75
+7015330170006592562E-75
-7015330170006592562E-74
+7185620434951919351E205
-1360520207561212395E198
+2178999185345151731E-184
-8691089486201567102E-218
+4345544743100783551E-218
-4357998370690303462E-184
+59825267349106892461E177
-62259110684423957791E47
+58380168477038565599E265
-62259110684423957791E48
-33584377202279118724E-252
-57484963479615354808E205
+71856204349519193510E204
-14371240869903838702E205
+36992084760177624177E-318
-73984169520355248354E-318
+99257763227713890244E-115
-87336362425182547697E-280
+7E289
-3E153
+6E153
-5E243
+7E-161
-7E-172
+8E-63
-7E-113
+8E126
-4E126
+5E125
-1E126
+8E-163
-1E-163
+2E-163
-4E-163
+51E195
-37E46
+74E46
-56E289
+69E-145
-70E-162
+56E-161
-21E-303
+34E-276
-68E-276
+85E-277
-87E-274
+829E102
-623E100
+723E-162
-457E-102
+914E-102
-323E-135
+151E176
-302E176
+921E90
-604E176
+823E-206
-463E-114
+348E-274
+9968E100
-6230E99
+1246E100
+6676E-296
-8345E-297
+1669E-296
-3338E-296
+3257E58
-6514E58
+2416E176
+8085E-63
-3234E-62
+1617E-62
-6468E-62
+53418E111
-60513E160
+26709E111
-99447E166
+12549E48
-25098E48
+50196E48
-62745E47
+83771E-73
-97451E-167
+86637E-203
-75569E-254
+473806E83
-947612E83
+292369E76
-584738E76
+933587E-140
-720919E-14
+535001E-149
-890521E-235
+548057E81
-706181E88
+820997E106
-320681E63
+928609E-261
-302276E-254
+151138E-254
+4691773E45
-9383546E45
+3059949E-243
-6119898E-243
+5356626E-213
-4877378E-199
+7716693E223
-5452869E109
+4590831E156
-9181662E156
-3714436E-261
+4643045E-262
-7428872E-261
+52942146E130
-27966061E145
+26471073E130
-55932122E145
+95412548E-99
-47706274E-99
+23853137E-99
-78493654E-301
+65346417E29
-51083099E167
+89396333E264
-84863171E114
+59540836E-251
-74426045E-252
+14885209E-251
-29770418E-251
+982161308E122
-245540327E122
+491080654E122
+525452622E-310
-771837113E-134
+820858081E-150
-262726311E-310
+923091487E209
-653777767E273
+842116236E-53
-741111169E-202
+839507247E-284
-951487269E-264
-9821613080E121
+6677856011E-31
-3573796826E-266
+7147593652E-266
-9981396317E-181
+3268888835E272
-2615111068E273
+1307555534E273
+2990671154E-190
-1495335577E-190
+5981342308E-190
-7476677885E-191
+82259684194E-202
-93227267727E-49
+41129842097E-202
-47584241418E-314
-79360293406E92
+57332259349E225
-57202326162E111
+86860597053E-206
-53827010643E-200
+53587107423E-61
+635007636765E200
+508006109412E201
-254003054706E201
+561029718715E-72
-897647549944E-71
+112205943743E-71
-873947086081E-236
+809184709177E116
-573112917422E81
+286556458711E81
+952805821491E-259
-132189992873E-44
-173696038493E-144
+1831132757599E-107
-9155663787995E-108
+7324531030396E-107
-9277338894969E-200
+8188292423973E287
-5672557437938E59
+2836278718969E59
-9995153153494E54
+9224786422069E-291
-3142213164987E-294
+6284426329974E-294
-8340483752889E-301
+67039371486466E89
-62150786615239E197
+33519685743233E89
-52563419496999E156
+32599460466991E-65
-41010988798007E-133
+65198920933982E-65
-82021977596014E-133
+80527976643809E61
-74712611505209E158
+53390939710959E261
-69277302659155E225
+46202199371337E-72
-23438635467783E-179
+41921560615349E-67
-92404398742674E-72
+738545606647197E124
-972708181182949E117
-837992143580825E87
+609610927149051E-255
-475603213226859E-41
+563002800671023E-177
-951206426453718E-41
+805416432656519E202
-530658674694337E159
+946574173863918E208
-318329953318553E113
-462021993713370E-73
+369617594970696E-72
+3666156212014994E233
-1833078106007497E233
+8301790508624232E174
-1037723813578029E174
+7297662880581139E-286
-5106185698912191E-276
+7487252720986826E-165
-3743626360493413E-165
+3773057430100257E230
-7546114860200514E230
+4321222892463822E58
-7793560217139653E51
+26525993941010681E112
-53051987882021362E112
+72844871414247907E77
-88839359596763261E105
+18718131802467065E-166
-14974505441973652E-165
+73429396004640239E106
-58483921078398283E57
+41391519190645203E165
-82783038381290406E165
+58767043776702677E-163
-90506231831231999E-129
+64409240769861689E-159
-77305427432277771E-190
+476592356619258326E273
-953184713238516652E273
+899810892172646163E283
-929167076892018333E187
+647761278967534239E-312
-644290479820542942E-180
+926145344610700019E-225
-958507931896511964E-246
+272104041512242479E200
-792644927852378159E79
+544208083024484958E200
-929963218616126365E290
+305574339166810102E-219
-152787169583405051E-219
+611148678333620204E-219
-763935847917025255E-220
+7439550220920798612E158
-3719775110460399306E158
+9299437776150998265E157
-7120190517612959703E120
+3507665085003296281E-73
-7015330170006592562E-73
-6684428762278255956E-294
-1088416166048969916E200
-8707329328391759328E200
+4439021781608558002E-65
-8878043563217116004E-65
+2219510890804279001E-65
+33051223951904955802E55
-56961524140903677624E120
+71201905176129597030E119
+14030660340013185124E-73
-17538325425016481405E-74
+67536228609141569109E-133
-35620497849450218807E-306
+66550376797582521751E-126
-71240995698900437614E-306
+3E24
-6E24
+6E26
-7E25
+1E-14
-2E-14
+4E-14
-8E-14
+5E26
-8E27
+1E27
-4E27
+9E-13
-7E-20
+56E25
-70E24
+51E26
+71E-17
-31E-5
+62E-5
-94E-8
+67E27
-81E24
+54E23
-54E25
+63E-22
-63E-23
+43E-4
-86E-4
+942E26
-471E25
+803E24
-471E26
-409E-21
+818E-21
-867E-8
+538E27
-857E24
+269E27
-403E26
+959E-7
-959E-6
+373E-27
-746E-27
+4069E24
-4069E23
-8138E24
+8294E-15
-4147E-14
+4147E-15
-8294E-14
+538E27
-2690E26
+269E27
-2152E27
+1721E-17
-7979E-27
+6884E-17
-8605E-18
+82854E27
-55684E24
+27842E24
-48959E25
+81921E-17
-76207E-8
+4147E-15
-41470E-16
+89309E24
+75859E26
-75859E25
+14257E-23
-28514E-23
+57028E-23
-71285E-24
+344863E27
-951735E27
+200677E23
-401354E24
+839604E-11
-209901E-11
+419802E-11
-537734E-24
+910308E26
-227577E26
+455154E26
-531013E25
+963019E-21
-519827E-13
+623402E-27
-311701E-27
+9613651E26
-9191316E23
+4595658E23
-2297829E23
-1679208E-11
+3379223E27
-6758446E27
+5444097E-21
-8399969E-27
+8366487E-16
-8366487E-15
+65060671E25
+65212389E23
+55544957E-13
-51040905E-20
+99585767E-22
-99585767E-23
+40978393E26
-67488159E24
+69005339E23
-81956786E26
-87105552E-21
+10888194E-21
-21776388E-21
+635806667E27
-670026614E25
+335013307E26
-335013307E25
+371790617E-24
-371790617E-25
+743581234E-24
-743581234E-25
+202464477E24
-404928954E24
+997853758E27
-997853758E26
+405498418E-17
-582579084E-14
+608247627E-18
-291289542E-14
-9537100005E26
+6358066670E27
-1271613334E27
+5229646999E-16
+5229646999E-17
+4429943614E24
-8859887228E24
+2214971807E24
-4176887093E26
+4003495257E-20
-4361901637E-23
+8723803274E-23
-8006990514E-20
+72835110098E27
-36417555049E27
+84279630104E25
-84279630104E24
+21206176437E-27
-66461566917E-22
+64808355539E-16
-84932679673E-19
+65205430094E26
-68384463429E25
+32602715047E26
-62662203426E27
+58784444678E-18
-50980203373E-21
+29392222339E-18
-75529940323E-27
-937495906299E26
+842642485799E-20
-387824150699E-23
+924948814726E-27
-775648301398E-23
+547075707432E25
+683844634290E24
-136768926858E25
+509802033730E-22
+101960406746E-21
-815683253968E-21
+7344124123524E24
-9180155154405E23
+6479463327323E27
-1836031030881E24
+4337269293039E-19
-4599163554373E-23
+9198327108746E-23
+4812803938347E27
-8412030890011E23
+9625607876694E27
-4739968828249E24
+9697183891673E-23
-7368108517543E-20
+51461358161422E25
-77192037242133E26
+77192037242133E25
-51461358161422E27
+43999661561541E-21
-87999323123082E-21
+48374886826137E-26
-57684246567111E-23
+87192805957686E23
-75108713005913E24
+64233110587487E27
-77577471133384E-23
+48485919458365E-24
-56908598265713E-26
+589722294620133E23
+652835804449289E-22
-656415363936202E-23
+579336749585745E-25
-381292764980839E-26
+965265859649698E23
-848925235434882E27
+536177612222491E23
-424462617717441E27
+276009279888989E-27
-608927158043691E-26
+552018559777978E-27
-425678377667758E-22
+8013702726927119E26
+8862627962362001E27
-5068007907757162E26
-7379714799828406E-23
+4114538064016107E-27
-3689857399914203E-23
+5575954851815478E23
+3395700941739528E27
+4115535777581961E-23
-8231071555163922E-23
+6550246696190871E-26
-68083046403986701E27
+43566388595783643E27
-87132777191567286E27
+59644881059342141E25
-83852770718576667E23
+99482967418206961E-25
-99482967418206961E-26
+87446669969994614E-27
-43723334984997307E-27
+5E24
-8E25
+1E25
-4E25
+2E-5
-5E-6
+4E-5
-3E-20
+3E27
-9E26
+7E25
-6E27
+2E-21
-5E-22
-4E-21
+87E25
-97E24
+82E-24
-41E-24
+76E-23
+83E25
-50E27
+25E27
-99E27
+97E-10
-57E-20
+997E23
+776E24
-388E24
+521E-10
-506E-26
+739E-10
-867E-7
-415E24
+332E25
-664E25
+291E-13
-982E-8
+582E-13
-491E-8
+4574E26
-8609E26
+2287E26
-4818E24
+6529E-8
-8151E-21
+1557E-12
-2573E-18
+4929E-16
-3053E-22
+9858E-16
-7767E-11
+54339E26
-62409E25
+32819E27
-89849E27
+63876E-20
-15969E-20
+31938E-20
-79845E-21
+89306E27
-25487E24
+79889E24
-97379E26
+81002E-8
-43149E-25
+40501E-8
-60318E-10
-648299E27
+780649E24
+720919E-14
-629703E-11
+557913E24
-847899E23
+565445E27
-736531E24
+680013E-19
-529981E-10
+382923E-23
-633614E-18
+2165479E27
-8661916E27
+4330958E27
-9391993E22
-5767352E-14
+7209190E-15
-1441838E-14
+8478990E22
+1473062E24
+8366487E-14
-8399969E-25
+9366737E-12
-9406141E-13
+65970979E24
-65060671E26
+54923002E27
-63846927E25
+99585767E-21
+67488159E25
-69005339E24
+81956786E27
-40978393E27
+77505754E-12
-38752877E-12
+82772981E-15
-95593517E-25
+200036989E25
-772686455E27
+859139907E23
-400073978E25
+569014327E-14
-794263862E-15
+397131931E-15
-380398957E-16
+567366773E27
-337440795E24
+134976318E25
-269952636E25
+932080597E-20
-331091924E-15
-413864905E-16
+8539246247E26
-5859139791E26
+6105010149E24
-3090745820E27
+3470877773E-20
-6136309089E-27
+8917758713E-19
-6941755546E-20
+9194900535E25
-1838980107E26
+7355920428E26
-3677960214E26
+8473634343E-17
-8870766274E-16
+4435383137E-16
-9598990129E-15
+71563496764E26
-89454370955E25
+17890874191E26
-35781748382E26
+57973447842E-19
-28986723921E-19
+76822711313E-19
-97699466874E-20
+67748656762E27
-19394840991E24
+38789681982E24
-33874328381E27
+54323763886E-27
-58987193887E-20
+27161881943E-27
-93042648033E-19
+520831059055E27
-768124264394E25
+384062132197E25
+765337749889E-25
+794368912771E25
-994162090146E23
+781652779431E26
+910077190046E-26
-455038595023E-26
+471897551096E-20
-906698409911E-21
+8854128003935E25
-8146122716299E27
+7083302403148E26
-3541651201574E26
+8394920649291E-25
-7657975756753E-22
+5473834002228E-20
-6842292502785E-21
-2109568884597E25
+8438275538388E25
-4219137769194E25
+3200141789841E-25
-8655689322607E-22
+6400283579682E-25
-8837719634493E-21
+19428217075297E24
-38856434150594E24
+77712868301188E24
-77192037242133E27
+76579757567530E-23
+15315951513506E-22
-38289878783765E-23
+49378033925202E25
-50940527102367E24
+98756067850404E25
-99589397544892E26
-56908598265713E-25
+97470695699657E-22
-35851901247343E-25
+154384074484266E27
-308768148968532E27
+910990389005985E23
+271742424169201E-27
-543484848338402E-27
+162192083357563E-26
-869254552770081E-23
+664831007626046E24
-332415503813023E24
+943701829041427E24
-101881054204734E24
+828027839666967E-27
-280276135608777E-27
+212839188833879E-21
-113817196531426E-25
+9711553197796883E27
-2739849386524269E26
+5479698773048538E26
+6124568318523113E-25
-1139777988171071E-24
+6322612303128019E-27
-2955864564844617E-25
-9994029144998961E25
-2971238324022087E27
-1656055679333934E-27
-1445488709150234E-26
+55824717499885172E27
-69780896874856465E26
+84161538867545199E25
-27912358749942586E27
+24711112462926331E-25
-12645224606256038E-27
-12249136637046226E-25
+74874448287465757E27
-35642836832753303E24
-71285673665506606E24
+43723334984997307E-26
+10182419849537963E-24
-93501703572661982E-26
import unittest, struct
import os
from test import test_support
class FormatFunctionsTestCase(unittest.TestCase):
......@@ -115,11 +116,25 @@ class IEEEFormatTestCase(unittest.TestCase):
self.assertEquals(pos_neg(), neg_neg())
class ReprTestCase(unittest.TestCase):
def test_repr(self):
floats_file = open(os.path.join(os.path.split(__file__)[0],
'floating_points.txt'))
for line in floats_file:
line = line.strip()
if not line or line.startswith('#'):
continue
v = eval(line)
self.assertEqual(v, eval(repr(v)))
floats_file.close()
def test_main():
test_support.run_unittest(
FormatFunctionsTestCase,
UnknownFormatTestCase,
IEEEFormatTestCase)
IEEEFormatTestCase,
ReprTestCase)
if __name__ == '__main__':
test_main()
......@@ -299,6 +299,7 @@ OBJECT_OBJS= \
Objects/genobject.o \
Objects/fileobject.o \
Objects/floatobject.o \
Objects/doubledigits.o \
Objects/frameobject.o \
Objects/funcobject.o \
Objects/intobject.o \
......
......@@ -12,6 +12,10 @@ What's New in Python 2.6 alpha 1?
Core and builtins
-----------------
- Issue #1580: New free format floating point representation based on
"Floating-Point Printer Sample Code", by Robert G. Burger. For example
repr(11./5) now returns '2.2' instead of '2.2000000000000002'.
- Issue #1538: Avoid copying string in split/rsplit if the split
char is not found.
......
/* Free-format floating point printer
*
* Based on "Floating-Point Printer Sample Code", by Robert G. Burger,
* http://www.cs.indiana.edu/~burger/fp/index.html
*/
#include "Python.h"
#if defined(__alpha) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64)
#define LITTLE_ENDIAN_IEEE_DOUBLE
#elif !(defined(__ppc__) || defined(sparc) || defined(__sgi) || defined(_IBMR2) || defined(hpux))
#error unknown machine type
#endif
#if defined(_M_IX86)
#define UNSIGNED64 unsigned __int64
#elif defined(__alpha)
#define UNSIGNED64 unsigned long
#else
#define UNSIGNED64 unsigned long long
#endif
#ifndef U32
#define U32 unsigned int
#endif
/* exponent stored + 1024, hidden bit to left of decimal point */
#define bias 1023
#define bitstoright 52
#define m1mask 0xf
#define hidden_bit 0x100000
#ifdef LITTLE_ENDIAN_IEEE_DOUBLE
struct dblflt {
unsigned int m4: 16;
unsigned int m3: 16;
unsigned int m2: 16;
unsigned int m1: 4;
unsigned int e: 11;
unsigned int s: 1;
};
#else
/* Big Endian IEEE Double Floats */
struct dblflt {
unsigned int s: 1;
unsigned int e: 11;
unsigned int m1: 4;
unsigned int m2: 16;
unsigned int m3: 16;
unsigned int m4: 16;
};
#endif
#define float_radix 2.147483648e9
typedef UNSIGNED64 Bigit;
#define BIGSIZE 24
#define MIN_E -1074
#define MAX_FIVE 325
#define B_P1 ((Bigit)1 << 52)
typedef struct {
int l;
Bigit d[BIGSIZE];
} Bignum;
static Bignum R, S, MP, MM, five[MAX_FIVE];
static Bignum S2, S3, S4, S5, S6, S7, S8, S9;
static int ruf, k, s_n, use_mp, qr_shift, sl, slr;
static void mul10(Bignum *x);
static void big_short_mul(Bignum *x, Bigit y, Bignum *z);
/*
static void print_big(Bignum *x);
*/
static int estimate(int n);
static void one_shift_left(int y, Bignum *z);
static void short_shift_left(Bigit x, int y, Bignum *z);
static void big_shift_left(Bignum *x, int y, Bignum *z);
static int big_comp(Bignum *x, Bignum *y);
static int sub_big(Bignum *x, Bignum *y, Bignum *z);
static void add_big(Bignum *x, Bignum *y, Bignum *z);
static int add_cmp(void);
static int qr(void);
/*static int _PyFloat_Digits(char *buf, double v, int *signum);*/
/*static void _PyFloat_DigitsInit(void);*/
#define ADD(x, y, z, k) {\
Bigit x_add, z_add;\
x_add = (x);\
if ((k))\
z_add = x_add + (y) + 1, (k) = (z_add <= x_add);\
else\
z_add = x_add + (y), (k) = (z_add < x_add);\
(z) = z_add;\
}
#define SUB(x, y, z, b) {\
Bigit x_sub, y_sub;\
x_sub = (x); y_sub = (y);\
if ((b))\
(z) = x_sub - y_sub - 1, b = (y_sub >= x_sub);\
else\
(z) = x_sub - y_sub, b = (y_sub > x_sub);\
}
#define MUL(x, y, z, k) {\
Bigit x_mul, low, high;\
x_mul = (x);\
low = (x_mul & 0xffffffff) * (y) + (k);\
high = (x_mul >> 32) * (y) + (low >> 32);\
(k) = high >> 32;\
(z) = (low & 0xffffffff) | (high << 32);\
}
#define SLL(x, y, z, k) {\
Bigit x_sll = (x);\
(z) = (x_sll << (y)) | (k);\
(k) = x_sll >> (64 - (y));\
}
static void
mul10(Bignum *x)
{
int i, l;
Bigit *p, k;
l = x->l;
for (i = l, p = &x->d[0], k = 0; i >= 0; i--)
MUL(*p, 10, *p++, k);
if (k != 0)
*p = k, x->l = l+1;
}
static void
big_short_mul(Bignum *x, Bigit y, Bignum *z)
{
int i, xl, zl;
Bigit *xp, *zp, k;
U32 high, low;
xl = x->l;
xp = &x->d[0];
zl = xl;
zp = &z->d[0];
high = y >> 32;
low = y & 0xffffffff;
for (i = xl, k = 0; i >= 0; i--, xp++, zp++) {
Bigit xlow, xhigh, z0, t, c, z1;
xlow = *xp & 0xffffffff;
xhigh = *xp >> 32;
z0 = (xlow * low) + k; /* Cout is (z0 < k) */
t = xhigh * low;
z1 = (xlow * high) + t;
c = (z1 < t);
t = z0 >> 32;
z1 += t;
c += (z1 < t);
*zp = (z1 << 32) | (z0 & 0xffffffff);
k = (xhigh * high) + (c << 32) + (z1 >> 32) + (z0 < k);
}
if (k != 0)
*zp = k, zl++;
z->l = zl;
}
/*
static void
print_big(Bignum *x)
{
int i;
Bigit *p;
printf("#x");
i = x->l;
p = &x->d[i];
for (p = &x->d[i]; i >= 0; i--) {
Bigit b = *p--;
printf("%08x%08x", (int)(b >> 32), (int)(b & 0xffffffff));
}
}
*/
static int
estimate(int n)
{
if (n < 0)
return (int)(n*0.3010299956639812);
else
return 1+(int)(n*0.3010299956639811);
}
static void
one_shift_left(int y, Bignum *z)
{
int n, m, i;
Bigit *zp;
n = y / 64;
m = y % 64;
zp = &z->d[0];
for (i = n; i > 0; i--) *zp++ = 0;
*zp = (Bigit)1 << m;
z->l = n;
}
static void
short_shift_left(Bigit x, int y, Bignum *z)
{
int n, m, i, zl;
Bigit *zp;
n = y / 64;
m = y % 64;
zl = n;
zp = &(z->d[0]);
for (i = n; i > 0; i--) *zp++ = 0;
if (m == 0)
*zp = x;
else {
Bigit high = x >> (64 - m);
*zp = x << m;
if (high != 0)
*++zp = high, zl++;
}
z->l = zl;
}
static void
big_shift_left(Bignum *x, int y, Bignum *z)
{
int n, m, i, xl, zl;
Bigit *xp, *zp, k;
n = y / 64;
m = y % 64;
xl = x->l;
xp = &(x->d[0]);
zl = xl + n;
zp = &(z->d[0]);
for (i = n; i > 0; i--) *zp++ = 0;
if (m == 0)
for (i = xl; i >= 0; i--) *zp++ = *xp++;
else {
for (i = xl, k = 0; i >= 0; i--)
SLL(*xp++, m, *zp++, k);
if (k != 0)
*zp = k, zl++;
}
z->l = zl;
}
static int
big_comp(Bignum *x, Bignum *y)
{
int i, xl, yl;
Bigit *xp, *yp;
xl = x->l;
yl = y->l;
if (xl > yl) return 1;
if (xl < yl) return -1;
xp = &x->d[xl];
yp = &y->d[xl];
for (i = xl; i >= 0; i--, xp--, yp--) {
Bigit a = *xp;
Bigit b = *yp;
if (a > b) return 1;
else if (a < b) return -1;
}
return 0;
}
static int
sub_big(Bignum *x, Bignum *y, Bignum *z)
{
int xl, yl, zl, b, i;
Bigit *xp, *yp, *zp;
xl = x->l;
yl = y->l;
if (yl > xl) return 1;
xp = &x->d[0];
yp = &y->d[0];
zp = &z->d[0];
for (i = yl, b = 0; i >= 0; i--)
SUB(*xp++, *yp++, *zp++, b);
for (i = xl-yl; b && i > 0; i--) {
Bigit x_sub;
x_sub = *xp++;
*zp++ = x_sub - 1;
b = (x_sub == 0);
}
for (; i > 0; i--) *zp++ = *xp++;
if (b) return 1;
zl = xl;
while (*--zp == 0) zl--;
z->l = zl;
return 0;
}
static void
add_big(Bignum *x, Bignum *y, Bignum *z)
{
int xl, yl, k, i;
Bigit *xp, *yp, *zp;
xl = x->l;
yl = y->l;
if (yl > xl) {
int tl;
Bignum *tn;
tl = xl; xl = yl; yl = tl;
tn = x; x = y; y = tn;
}
xp = &x->d[0];
yp = &y->d[0];
zp = &z->d[0];
for (i = yl, k = 0; i >= 0; i--)
ADD(*xp++, *yp++, *zp++, k);
for (i = xl-yl; k && i > 0; i--) {
Bigit z_add;
z_add = *xp++ + 1;
k = (z_add == 0);
*zp++ = z_add;
}
for (; i > 0; i--) *zp++ = *xp++;
if (k)
*zp = 1, z->l = xl+1;
else
z->l = xl;
}
static int
add_cmp()
{
int rl, ml, sl, suml;
static Bignum sum;
rl = R.l;
ml = (use_mp ? MP.l : MM.l);
sl = S.l;
suml = rl >= ml ? rl : ml;
if ((sl > suml+1) || ((sl == suml+1) && (S.d[sl] > 1))) return -1;
if (sl < suml) return 1;
add_big(&R, (use_mp ? &MP : &MM), &sum);
return big_comp(&sum, &S);
}
static int
qr()
{
if (big_comp(&R, &S5) < 0)
if (big_comp(&R, &S2) < 0)
if (big_comp(&R, &S) < 0)
return 0;
else {
sub_big(&R, &S, &R);
return 1;
}
else if (big_comp(&R, &S3) < 0) {
sub_big(&R, &S2, &R);
return 2;
}
else if (big_comp(&R, &S4) < 0) {
sub_big(&R, &S3, &R);
return 3;
}
else {
sub_big(&R, &S4, &R);
return 4;
}
else if (big_comp(&R, &S7) < 0)
if (big_comp(&R, &S6) < 0) {
sub_big(&R, &S5, &R);
return 5;
}
else {
sub_big(&R, &S6, &R);
return 6;
}
else if (big_comp(&R, &S9) < 0)
if (big_comp(&R, &S8) < 0) {
sub_big(&R, &S7, &R);
return 7;
}
else {
sub_big(&R, &S8, &R);
return 8;
}
else {
sub_big(&R, &S9, &R);
return 9;
}
}
#define OUTDIG(d) { *buf++ = (d) + '0'; *buf = 0; return k; }
int
_PyFloat_Digits(char *buf, double v, int *signum)
{
struct dblflt *x;
int sign, e, f_n, m_n, i, d, tc1, tc2;
Bigit f;
/* decompose float into sign, mantissa & exponent */
x = (struct dblflt *)&v;
sign = x->s;
e = x->e;
f = (Bigit)(x->m1 << 16 | x->m2) << 32 | (U32)(x->m3 << 16 | x->m4);
if (e != 0) {
e = e - bias - bitstoright;
f |= (Bigit)hidden_bit << 32;
}
else if (f != 0)
/* denormalized */
e = 1 - bias - bitstoright;
*signum = sign;
if (f == 0) {
*buf++ = '0';
*buf = 0;
return 0;
}
ruf = !(f & 1); /* ruf = (even? f) */
/* Compute the scaling factor estimate, k */
if (e > MIN_E)
k = estimate(e+52);
else {
int n;
Bigit y;
for (n = e+52, y = (Bigit)1 << 52; f < y; n--) y >>= 1;
k = estimate(n);
}
if (e >= 0)
if (f != B_P1)
use_mp = 0, f_n = e+1, s_n = 1, m_n = e;
else
use_mp = 1, f_n = e+2, s_n = 2, m_n = e;
else
if ((e == MIN_E) || (f != B_P1))
use_mp = 0, f_n = 1, s_n = 1-e, m_n = 0;
else
use_mp = 1, f_n = 2, s_n = 2-e, m_n = 0;
/* Scale it! */
if (k == 0) {
short_shift_left(f, f_n, &R);
one_shift_left(s_n, &S);
one_shift_left(m_n, &MM);
if (use_mp) one_shift_left(m_n+1, &MP);
qr_shift = 1;
}
else if (k > 0) {
s_n += k;
if (m_n >= s_n)
f_n -= s_n, m_n -= s_n, s_n = 0;
else
f_n -= m_n, s_n -= m_n, m_n = 0;
short_shift_left(f, f_n, &R);
big_shift_left(&five[k-1], s_n, &S);
one_shift_left(m_n, &MM);
if (use_mp) one_shift_left(m_n+1, &MP);
qr_shift = 0;
}
else {
Bignum *power = &five[-k-1];
s_n += k;
big_short_mul(power, f, &S);
big_shift_left(&S, f_n, &R);
one_shift_left(s_n, &S);
big_shift_left(power, m_n, &MM);
if (use_mp) big_shift_left(power, m_n+1, &MP);
qr_shift = 1;
}
/* fixup */
if (add_cmp() <= -ruf) {
k--;
mul10(&R);
mul10(&MM);
if (use_mp) mul10(&MP);
}
/*
printf("\nk = %d\n", k);
printf("R = "); print_big(&R);
printf("\nS = "); print_big(&S);
printf("\nM- = "); print_big(&MM);
if (use_mp) printf("\nM+ = "), print_big(&MP);
putchar('\n');
fflush(0);
*/
if (qr_shift) {
sl = s_n / 64;
slr = s_n % 64;
}
else {
big_shift_left(&S, 1, &S2);
add_big(&S2, &S, &S3);
big_shift_left(&S2, 1, &S4);
add_big(&S4, &S, &S5);
add_big(&S4, &S2, &S6);
add_big(&S4, &S3, &S7);
big_shift_left(&S4, 1, &S8);
add_big(&S8, &S, &S9);
}
again:
if (qr_shift) { /* Take advantage of the fact that S = (ash 1 s_n) */
if (R.l < sl)
d = 0;
else if (R.l == sl) {
Bigit *p;
p = &R.d[sl];
d = *p >> slr;
*p &= ((Bigit)1 << slr) - 1;
for (i = sl; (i > 0) && (*p == 0); i--) p--;
R.l = i;
}
else {
Bigit *p;
p = &R.d[sl+1];
d = *p << (64 - slr) | *(p-1) >> slr;
p--;
*p &= ((Bigit)1 << slr) - 1;
for (i = sl; (i > 0) && (*p == 0); i--) p--;
R.l = i;
}
}
else /* We need to do quotient-remainder */
d = qr();
tc1 = big_comp(&R, &MM) < ruf;
tc2 = add_cmp() > -ruf;
if (!tc1)
if (!tc2) {
mul10(&R);
mul10(&MM);
if (use_mp) mul10(&MP);
*buf++ = d + '0';
goto again;
}
else
OUTDIG(d+1)
else
if (!tc2)
OUTDIG(d)
else {
big_shift_left(&R, 1, &MM);
if (big_comp(&MM, &S) == -1)
OUTDIG(d)
else
OUTDIG(d+1)
}
}
void
_PyFloat_DigitsInit()
{
int n, i, l;
Bignum *b;
Bigit *xp, *zp, k;
five[0].l = l = 0;
five[0].d[0] = 5;
for (n = MAX_FIVE-1, b = &five[0]; n > 0; n--) {
xp = &b->d[0];
b++;
zp = &b->d[0];
for (i = l, k = 0; i >= 0; i--)
MUL(*xp++, 5, *zp++, k);
if (k != 0)
*zp = k, l++;
b->l = l;
}
/*
for (n = 1, b = &five[0]; n <= MAX_FIVE; n++) {
big_shift_left(b++, n, &R);
print_big(&R);
putchar('\n');
}
fflush(0);
*/
}
......@@ -306,6 +306,107 @@ PyFloat_AsStringEx(char *buf, PyFloatObject *v, int precision)
format_float(buf, 100, v, precision);
}
/* The following function is based on Tcl_PrintDouble,
* from tclUtil.c.
*/
#define is_infinite(d) ( (d) > DBL_MAX || (d) < -DBL_MAX )
#define is_nan(d) ((d) != (d))
static void
format_double_repr(char *dst, double value)
{
char *p, c;
int exp;
int signum;
char buffer[30];
/*
* Handle NaN.
*/
if (is_nan(value)) {
strcpy(dst, "nan");
return;
}
/*
* Handle infinities.
*/
if (is_infinite(value)) {
if (value < 0) {
strcpy(dst, "-inf");
} else {
strcpy(dst, "inf");
}
return;
}
/*
* Ordinary (normal and denormal) values.
*/
exp = _PyFloat_Digits(buffer, value, &signum)+1;
if (signum) {
*dst++ = '-';
}
p = buffer;
if (exp < -3 || exp > 17) {
/*
* E format for numbers < 1e-3 or >= 1e17.
*/
*dst++ = *p++;
c = *p;
if (c != '\0') {
*dst++ = '.';
while (c != '\0') {
*dst++ = c;
c = *++p;
}
}
sprintf(dst, "e%+d", exp-1);
} else {
/*
* F format for others.
*/
if (exp <= 0) {
*dst++ = '0';
}
c = *p;
while (exp-- > 0) {
if (c != '\0') {
*dst++ = c;
c = *++p;
} else {
*dst++ = '0';
}
}
*dst++ = '.';
if (c == '\0') {
*dst++ = '0';
} else {
while (++exp < 0) {
*dst++ = '0';
}
while (c != '\0') {
*dst++ = c;
c = *++p;
}
}
*dst++ = '\0';
}
}
static void
format_float_repr(char *buf, PyFloatObject *v)
{
assert(PyFloat_Check(v));
format_double_repr(buf, PyFloat_AS_DOUBLE(v));
}
/* Macro and helper that convert PyObject obj to a C double and store
the value in dbl; this replaces the functionality of the coercion
slot function. If conversion to double raises an exception, obj is
......@@ -390,8 +491,8 @@ float_print(PyFloatObject *v, FILE *fp, int flags)
static PyObject *
float_repr(PyFloatObject *v)
{
char buf[100];
format_float(buf, sizeof(buf), v, PREC_REPR);
char buf[30];
format_float_repr(buf, v);
return PyString_FromString(buf);
}
......@@ -1290,6 +1391,9 @@ _PyFloat_Init(void)
double_format = detected_double_format;
float_format = detected_float_format;
/* Initialize floating point repr */
_PyFloat_DigitsInit();
}
void
......
......@@ -485,6 +485,9 @@
RelativePath="..\Objects\dictobject.c">
</File>
<File
RelativePath="..\Objects\doubledigits.c">
</File>
<File
RelativePath="..\PC\dl_nt.c">
</File>
<File
......
......@@ -819,6 +819,10 @@
RelativePath="..\..\Objects\dictobject.c"
>
</File>
<File
RelativePath="..\..\Objects\doubledigits.c"
>
</File>
<File
RelativePath="..\..\Objects\enumobject.c"
>
......
......@@ -1370,6 +1370,10 @@
RelativePath="..\Objects\dictobject.c"
>
</File>
<File
RelativePath="..\Objects\doubledigits.c"
>
</File>
<File
RelativePath="..\Objects\enumobject.c"
>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment