summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/floatobject.h4
-rw-r--r--Lib/test/floating_points.txt1021
-rw-r--r--Lib/test/test_float.py17
-rw-r--r--Makefile.pre.in1
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/doubledigits.c601
-rw-r--r--Objects/floatobject.c108
-rw-r--r--PCbuild/pythoncore.vcproj3
-rw-r--r--PCbuild8/pythoncore/pythoncore.vcproj4
-rw-r--r--PCbuild9/pythoncore.vcproj4
10 files changed, 1764 insertions, 3 deletions
diff --git a/Include/floatobject.h b/Include/floatobject.h
index be1a80c..85537f1 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -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).
diff --git a/Lib/test/floating_points.txt b/Lib/test/floating_points.txt
new file mode 100644
index 0000000..70d21ea
--- /dev/null
+++ b/Lib/test/floating_points.txt
@@ -0,0 +1,1021 @@
+# 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
diff --git a/Lib/test/test_float.py b/Lib/test/test_float.py
index 1c74c96..327eeae 100644
--- a/Lib/test/test_float.py
+++ b/Lib/test/test_float.py
@@ -1,5 +1,6 @@
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()
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 70e5b0e..c2a061a 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -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 \
diff --git a/Misc/NEWS b/Misc/NEWS
index c086be9..679f1fe 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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.
diff --git a/Objects/doubledigits.c b/Objects/doubledigits.c
new file mode 100644
index 0000000..1f1c91c
--- /dev/null
+++ b/Objects/doubledigits.c
@@ -0,0 +1,601 @@
+/* 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);
+ */
+}
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index c76956a..e92dab9 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -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
diff --git a/PCbuild/pythoncore.vcproj b/PCbuild/pythoncore.vcproj
index 556b144..930deca 100644
--- a/PCbuild/pythoncore.vcproj
+++ b/PCbuild/pythoncore.vcproj
@@ -485,6 +485,9 @@
RelativePath="..\Objects\dictobject.c">
</File>
<File
+ RelativePath="..\Objects\doubledigits.c">
+ </File>
+ <File
RelativePath="..\PC\dl_nt.c">
</File>
<File
diff --git a/PCbuild8/pythoncore/pythoncore.vcproj b/PCbuild8/pythoncore/pythoncore.vcproj
index 6dd6867..f903c49 100644
--- a/PCbuild8/pythoncore/pythoncore.vcproj
+++ b/PCbuild8/pythoncore/pythoncore.vcproj
@@ -820,6 +820,10 @@
>
</File>
<File
+ RelativePath="..\..\Objects\doubledigits.c"
+ >
+ </File>
+ <File
RelativePath="..\..\Objects\enumobject.c"
>
</File>
diff --git a/PCbuild9/pythoncore.vcproj b/PCbuild9/pythoncore.vcproj
index df1f512..ba41095 100644
--- a/PCbuild9/pythoncore.vcproj
+++ b/PCbuild9/pythoncore.vcproj
@@ -1371,6 +1371,10 @@
>
</File>
<File
+ RelativePath="..\Objects\doubledigits.c"
+ >
+ </File>
+ <File
RelativePath="..\Objects\enumobject.c"
>
</File>