about summary refs log tree commit diff stats
path: root/js/games/nluqo.github.io/~bh/ss-pics/fourplus.jpg
blob: 9ac494c7374de40ad5c043ff3e22e2b8d690c1e0 (plain)
ofshex dumpascii
0000 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 00 00 01 00 01 00 00 ff fe 00 48 43 52 45 41 54 4f 52 3a ......JFIF.............HCREATOR:
0020 20 58 56 20 56 65 72 73 69 6f 6e 20 33 2e 31 30 61 20 20 52 65 76 3a 20 31 32 2f 32 39 2f 39 34 .XV.Version.3.10a..Rev:.12/29/94
0040 20 20 51 75 61 6c 69 74 79 20 3d 20 37 35 2c 20 53 6d 6f 6f 74 68 69 6e 67 20 3d 20 30 0a ff db ..Quality.=.75,.Smoothing.=.0...
0060 00 43 00 08 06 06 07 06 05 08 07 07 07 09 09 08 0a 0c 14 0d 0c 0b 0b 0c 19 12 13 0f 14 1d 1a 1f .C..............................
0080 1e 1d 1a 1c 1c 20 24 2e 27 20 22 2c 23 1c 1c 28 37 29 2c 30 31 34 34 34 1f 27 39 3d 38 32 3c 2e ......$.'.",#..(7),01444.'9=82<.
00a0 33 34 32 ff c0 00 0b 08 00 84 00 94 01 01 11 00 ff c4 00 1f 00 00 01 05 01 01 01 01 01 01 00 00 342.............................
00c0 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b ff c4 00 b5 10 00 02 01 03 03 02 04 03 05 05 ................................
00e0 04 04 00 00 01 7d 01 02 03 00 04 11 05 12 21 31 41 06 13 51 61 07 22 71 14 32 81 91 a1 08 23 42 .....}........!1A..Qa."q.2....#B
0100 b1 c1 15 52 d1 f0 24 33 62 72 82 09 0a 16 17 18 19 1a 25 26 27 28 29 2a 34 35 36 37 38 39 3a 43 ...R..$3br........%&'()*456789:C
0120 44 45 46 47 48 49 4a 53 54 55 56 57 58 59 5a 63 64 65 66 67 68 69 6a 73 74 75 76 77 78 79 7a 83 DEFGHIJSTUVWXYZcdefghijstuvwxyz.
0140 84 85 86 87 88 89 8a 92 93 94 95 96 97 98 99 9a a2 a3 a4 a5 a6 a7 a8 a9 aa b2 b3 b4 b5 b6 b7 b8 ................................
0160 b9 ba c2 c3 c4 c5 c6 c7 c8 c9 ca d2 d3 d4 d5 d6 d7 d8 d9 da e1 e2 e3 e4 e5 e6 e7 e8 e9 ea f1 f2 ................................
0180 f3 f4 f5 f6 f7 f8 f9 fa ff da 00 08 01 01 00 00 3f 00 f7 fa 28 a2 8a 28 a2 8a 28 a2 8a 28 a2 8a ................?...(..(..(..(..
01a0 28 a2 8a 28 a2 8a 29 19 95 14 b3 10 aa 06 49 27 00 0a e7 57 59 d5 35 b7 23 c3 f6 f0 45 64 0f fc (..(..).......I'...WY.5.#...Ed..
01c0 84 ef 95 9a 39 46 33 98 62 52 1a 45 ed b8 b2 0e 72 bb c5 3f fe 11 fd 52 44 1e 77 8b b5 7d e7 96 ....9F3.bR.E....r..?...RD.w..}..
01e0 10 c3 6a 8b 9f 60 61 24 0f a9 3f 53 43 e8 fa fd b0 12 58 f8 9e 5b 89 00 39 8f 53 b4 86 48 cf a7 ..j..`a$..?SC.....X..[..9.S..H..
0200 fa 95 89 81 f7 c9 fa 54 b6 1e 20 66 d4 53 4a d5 ec ce 9d a9 c8 ac d1 27 99 e6 43 70 06 73 e5 49 .......T...f.SJ........'..Cp.s.I
0220 81 b8 80 32 54 85 60 32 71 8e 6b 6e 8a 28 a2 8a 28 a2 8a 28 a2 8a e6 ef 54 f8 8f 5d 9b 48 65 0d ...2T.`2q.kn.(..(..(....T..].He.
0240 a4 58 05 37 c0 83 fe 91 33 00 c9 09 ec 50 29 57 61 fc 5b 91 7a 6f 07 a4 a8 a7 b9 82 d6 31 25 c4 .X.7....3....P)Wa.[.zo.......1%.
0260 d1 c2 85 82 06 91 82 82 c4 e0 0c 9e e4 90 05 4b 54 b5 5d 2e d7 59 b0 7b 3b b5 6d 8c 43 2b a3 6d ...............KT.]..Y.{;.m.C+.m
0280 78 9c 72 ae 8c 39 56 07 90 47 43 54 bc 3b a8 5d 4f 15 ce 9b a9 c8 24 d5 34 e7 11 4f 20 40 82 75 x.r..9V..GCT.;.]O.....$.4..O.@.u
02a0 23 29 30 51 d0 30 eb d8 32 ba 8f bb 5b 54 51 45 14 51 45 14 51 45 15 cf f8 28 79 9e 17 b7 bf 65 #)0Q.0..2...[TQE.QE.QE...(y....e
02c0 01 f5 27 93 50 6f 5c 4c e6 45 04 f7 c2 32 af d1 45 74 15 ca 7c 41 ff 00 91 76 d7 fe c2 96 5f fa ..'.Po\L.E...2..Et..|A...v...._.
02e0 50 95 d5 d1 5c fd ce 2d bc 7f a7 ba 96 51 7b a7 4f 14 b8 3c 3b 45 24 6d 1e 7e 82 49 bf ef a3 5d P...\..-.....Q{.O..<;E$m.~.I...]
0300 05 14 51 45 14 51 45 14 51 45 73 fe 09 25 3c 25 65 66 c4 17 d3 f7 e9 ec 47 73 03 b4 39 fc 76 67 ..QE.QE.QEs..%<%ef......Gs..9.vg
0320 f1 ad 4d 57 4a b1 d6 f4 d9 b4 ed 4a dd 6e 2d 26 c7 99 13 12 03 60 86 1d 3d c0 35 e7 1e 34 f8 73 ..MWJ......J.n-&.....`..=.5..4.s
0340 e1 1d 37 44 82 7b 3d 12 08 a4 6b fb 48 8b 06 7e 55 e6 45 61 c9 ee 09 15 d4 5a 7c 34 f0 75 85 ec ..7D.{=...k.H..~U.Ea.....Z|4.u..
0360 17 96 ba 14 11 dc 5b c8 b2 c4 e1 df 2a ca 72 0f 5e c4 57 57 5c fd de db 8f 1f 69 71 29 dd f6 5d ......[.....*.r.^.WW\.....iq)..]
0380 3e e6 69 00 fe 02 ef 12 a6 7e a0 4b 8f f7 4f a5 74 14 51 45 14 51 45 14 51 45 15 cc cf 28 f0 cf >.i......~.K..O.t.QE.QE.QE...(..
03a0 88 e4 ba 95 58 69 3a bc 89 e6 ca 00 db 6d 75 80 8a cc 7b 2c 8a 11 73 d0 32 8f ef f1 d3 55 4d 43 ....Xi:......mu...{,..s.2....UMC
03c0 4d b4 d5 6d d6 de f6 2f 36 25 95 26 0b b8 ae 1d 18 32 9e 08 e8 40 35 6e aa ea 3a 8d a6 93 a7 cf M..m.../6%.&.....2...@5n..:.....
03e0 7f 7f 3a c1 6b 02 ee 92 46 ed d8 00 07 24 93 80 00 e4 92 00 e4 d6 6f 87 ac ee 4b 5d eb 1a 84 66 ..:.k...F....$........o...K]...f
0400 3b dd 45 95 84 2d 9c db c0 a0 f9 51 1e 48 dc 01 66 6c 71 b9 db 19 18 ad ca 28 a2 8a 28 a2 8a 28 ;.E..-.....Q.H..flq......(..(..(
0420 a2 8a 8e 78 22 b9 b7 92 de e2 24 96 19 54 a4 91 c8 a1 95 d4 8c 10 41 e0 82 3b 57 1b a4 cd ad 69 ...x".....$..T........A..;W....i
0440 d7 37 f6 da 34 07 55 d0 ac a5 f2 23 4b ab 8d b7 01 c7 df 48 64 23 12 22 7d c0 1c 83 b8 38 2f 85 .7..4.U....#K......Hd#."}....8/.
0460 15 ae be 2c b7 42 52 f3 4a d7 2d 26 1d 63 3a 6c b3 ff 00 e3 f0 87 43 f8 35 23 78 96 e2 e8 94 d2 ...,.BR.J.-&.c:l......C.5#x.....
0480 74 0d 52 e9 b8 02 4b 98 be c7 12 9f f6 bc dd af 8f 75 46 fa 56 76 99 05 c6 a9 e2 8b 88 fc 4e 61 t.R...K..........uF.Vv........Na
04a0 7b fd 3d 92 ea c2 d2 16 cd ba 46 cb 81 2a 83 cb c8 ae 24 42 cd d3 00 85 4d fc f6 34 51 45 14 51 {.=.......F..*....$B....M..4QE.Q
04c0 45 14 51 45 14 56 37 88 f5 29 ec ec a2 b4 b0 65 1a a6 a1 27 d9 ac f3 83 b1 88 25 a4 20 f0 42 28 E.QE.V7..).....e...'......%...B(
04e0 67 20 f5 da 17 ab 0a bd a6 69 b6 fa 46 99 6f a7 da 29 58 60 40 8b 9e 59 bd 59 8f 76 27 24 9e e4 g........i..F.o..)X`@..Y.Y.v'$..
0500 93 56 e8 ac 2f 12 da dc 2c 56 fa cd 84 6f 25 f6 98 5a 41 12 67 37 10 9c 79 b1 60 75 2c a0 15 1f .V../...,V...o%..ZA.g7..y.`u,...
0520 df 44 cf 00 d6 bd a5 d4 17 d6 70 5d db 48 25 b7 9e 35 96 29 17 a3 2b 0c 82 3e a0 d4 d4 51 45 14 .D........p].H%..5.)..+..>...QE.
0540 51 45 14 56 56 a3 e2 4d 2b 4b ba 5b 4b 8b 96 7b c6 5d e2 d2 da 27 9e 7d bf de f2 e3 0c c1 78 fb QE.VV..M+K.[K..{.]...'.}......x.
0560 d8 c7 bd 55 5f 11 5f c8 a1 a3 f0 9e b6 c8 7e eb 16 b5 4c 8f f7 5a 70 c3 f1 00 d1 1f 8c 34 c5 91 ...U_._.......~...L..Zp......4..
0580 21 d4 52 ef 49 99 db 60 5d 46 06 89 0b 76 51 2f 31 b1 3d 82 b9 26 a3 d0 73 ac ea 77 1e 24 7c f9 !.R.I..`]F...vQ/1.=..&..s..w.$|.
05a0 0e a6 db 4d 53 91 fe 8e 08 2d 2e 3a 7e f1 94 10 47 54 48 cf 73 5d 1d 14 51 5c a5 b5 ed 9f 84 35 ...MS....-.:~...GTH.s]..Q\.....5
05c0 4b ad 36 fe e6 0b 3d 26 e3 7d e5 8c d3 c8 b1 c7 19 2d fb d8 72 4f 66 60 eb 9e d2 10 38 4a b6 be K.6...=&.}.......-..rOf`....8J..
05e0 2a 4b 92 0e 99 a2 eb 1a 82 11 9f 32 3b 61 02 63 b1 0d 3b 46 18 7b ae 45 29 f1 3c 90 30 fb 7f 87 *K.........2;a.c..;F.{.E).<.0...
0600 75 bb 48 cf 49 3e ce 97 23 3f ee db bc 8c 3f 2c 56 9e 9b aa d8 6b 16 bf 69 d3 af 21 ba 84 36 d2 u.H.I>..#?....?,V....k..i..!..6.
0620 d1 38 6d ad 80 4a b0 fe 16 19 19 07 91 57 28 a2 8a 28 ae 77 55 bc d4 75 4d 50 e8 9a 3c c6 d9 22 .8m..J.......W(..(.wU..uMP..<.."
0640 01 b5 0d 40 00 c6 00 46 44 51 83 90 65 61 ce 48 21 14 82 41 2c a0 ea e9 9a 4d 86 8f 6e d0 58 5b ...@...FDQ..ea.H!..A,....M..n.X[
0660 2c 2a ee 64 91 b2 59 e5 73 d5 dd 8e 59 d8 f7 66 24 9f 5a bb 4c 9a 18 ae 21 92 19 a3 49 22 91 4a ,*.d..Y.s...Y..f$.Z.L...!...I".J
0680 3a 3a 82 ac a4 60 82 0f 50 6b 95 b8 8e 5f 04 bb 5e 5b 99 66 f0 e1 23 ed 16 bc b1 d3 c7 4f 32 2e ::...`..Pk..._..^[.f..#......O2.
06a0 fe 50 fe 24 fe 11 f3 2e 00 2a 7a d0 41 00 83 90 68 a2 a8 6a fa b5 be 8d 63 f6 99 c3 3b 33 ac 50 .P.$.....*z.A...h..j....c...;3.P
06c0 c2 98 df 3c ac 70 a8 a0 f7 27 f0 03 24 90 01 22 8d 8e 80 66 bd 8b 56 d6 ca 5d ea 68 3f 74 83 26 ...<.p...'..$.."...f..V..].h?t.&
06e0 1b 3c f6 89 4f 7e c6 42 37 37 fb 23 0a 37 68 ac 7d 4f c3 f0 dd de 2e a7 65 27 d8 75 78 d7 6a 5d .<..O~.B77.#.7h.}O......e'.ux.j]
0700 c6 b9 de 3f b9 2a f0 24 4f 63 c8 ea a5 4f 35 26 8d ab 8d 4d 27 82 68 d6 0d 46 cd c4 57 76 c1 b7 ...?.*.$Oc...O5&...M'.h..F..Wv..
0720 79 6d 8c 82 0f 1b 91 87 2a d8 e4 75 c1 04 0d 4a 28 a2 a9 ea da 8c 7a 46 8d 7d a9 ca 8c f1 d9 db ym......*..u...J(.....zF.}......
0740 c9 70 ea bd 48 45 2c 40 f7 e2 aa f8 6f 4b 93 49 d0 e0 86 e4 a3 5f 4b 99 ef 64 5c 7e f2 e1 ce e9 .p..HE,@....oK.I....._K..d\~....
0760 1b a0 e3 71 20 7a 00 07 6a d6 ae 4b c7 be 2a 97 c3 da 1d d4 7a 6a f9 ba bb 5a cb 3c 4b 8c 88 63 ...q.z..j..K..*.....zj...Z.<K..c
0780 41 96 95 fb 00 38 03 3f 79 8a 8e 99 22 b7 c2 3b 99 ef 3e 18 e9 17 17 33 49 3c f2 35 c3 3c b2 b1 A....8.?y..."..;..>....3I<.5.<..
07a0 66 63 e7 c9 c9 27 92 6b b5 20 30 20 80 41 e0 83 de b9 ff 00 09 83 67 6d 7f a2 13 94 d2 6e 8d bc fc...'.k..0..A........gm.....n..
07c0 1c 92 7c 86 45 92 21 cf 38 55 90 47 9e 73 e5 93 5d 0d 15 cf 46 3f b5 3c 6f 3b b6 5a db 47 81 63 ..|.E.!.8U.G.s..]...F?.<o;.Z.G.c
07e0 8c 63 e5 fb 4c a0 97 27 fd a5 8b cb 00 f6 13 38 ef 5d 0d 70 3f da cb af 7c 43 d7 b4 2d 47 53 96 .c..L..'.......8.].p?...|C..-GS.
0800 ca c7 48 86 07 8a de 0b a6 b7 79 cb 26 e7 91 9d 4a be 17 20 60 1d bc 82 7b 57 2f ad df 6a 3e 08 ..H.......y.&...J...`...{W/..j>.
0820 f8 bd e1 fd 33 47 d4 ef 66 d3 35 3f 29 26 d3 ee ee 5e e1 63 0d 21 46 65 de 49 5f ef 03 9e a0 f6 ....3G..f.5?)&...^.c.!Fe.I_.....
0840 e2 bd 9a b9 ed 68 7f 66 f8 8b 48 d5 d3 2a 93 c9 fd 9d 79 e8 51 f2 62 63 ee 25 da a3 d3 ce 7f 5a .....h.f..H..*....y.Q.bc.%.....Z
0860 e8 68 a2 8a e7 fc 72 09 f0 3e b1 c6 50 5b 31 90 7f d3 31 cb ff 00 e3 b9 ae 82 b3 f5 ad 62 db 43 .h....r..>..P[1...1..........b.C
0880 d3 9a ee e3 73 16 65 8a 18 53 97 9e 56 38 48 d0 77 62 78 f4 1c 93 80 09 ae 4f c4 1a 55 cd 8f c3 ....s.e..S..V8H.wbx......O..U...
08a0 7f 14 5e 6a 73 25 c6 ad 7b 63 2b dc c8 83 08 80 21 db 12 77 d8 80 90 33 d4 96 63 cb 1a 5f 83 7f ..^js%..{c+.....!..w...3..c.._..
08c0 f2 4a 34 5f fb 6f ff 00 a3 e4 ae ee b9 fd 3b 07 c7 7a f1 8f ee 0b 3b 25 7f 4f 33 33 93 f8 ed 31 .J4_.o........;..z....;%.O33...1
08e0 fe 95 d0 51 58 5a 07 fc 86 7c 53 ff 00 61 44 ff 00 d2 3b 6a dd ae 6f c4 50 69 8b a9 58 4a 7c 33 ...QXZ...|S..aD...;j..o.Pi..XJ|3
0900 0e ad ac 4e db 6d a5 6b 55 22 1d 9f 36 e9 26 2a 7c b4 52 47 ab 64 fc aa c7 8a e0 ee b5 4f f8 41 ...N.m.kU"..6.&*|.RG.d.......O.A
0920 fc 67 6d af 78 eb 4c 17 17 97 e8 61 87 55 b4 b8 33 c3 68 01 c7 96 91 32 29 8c 05 24 93 96 63 96 .gm.x.L....a.U..3.h....2)..$..c.
0940 c6 77 30 af 60 04 11 90 72 0d 61 78 bb fe 40 d6 ff 00 f6 14 d3 ff 00 f4 b2 1a dd a2 8a 2a ae a5 .w0.`...r.ax..@..............*..
0960 61 0e a9 a5 dd e9 d7 3b bc 8b a8 5e 09 36 9c 1d ac a5 4e 0f d0 d5 1f 0c ea 33 ea 1a 2c 62 fb 8d a......;...^.6....N......3..,b..
0980 4a d4 9b 5b e5 c6 31 32 70 c4 0f ee b7 0e be aa ea 7b d3 f5 df 0d e9 3e 26 b6 8a df 57 b5 37 11 J..[..12p........{.....>&...W.7.
09a0 43 27 9b 18 12 bc 65 5b 04 67 28 41 e8 4f e7 5c 1f 8d fe 1e f8 47 47 f0 46 b3 7f 0d 83 c5 34 36 C'....e[.g(A.O.\.....GG.F.....46
09c0 ae 62 76 bd 9d 80 72 30 bc 17 20 f2 47 06 99 f0 6f c2 ba 37 fc 21 ba 2f 88 be ca ff 00 da 9f bf .bv...r0....G...o..7.!./........
09e0 fd f7 9f 26 3f d6 48 9f 73 76 df bb c7 4f 7e b5 ea 33 4d 15 bc 12 4f 3c 89 14 31 a9 77 91 d8 2a ...&?.H.sv...O~..3M...O<..1.w..*
0a00 aa 81 92 49 3d 00 1d eb 0f c2 89 24 d6 57 7a c4 c8 d1 be ad 72 6e d6 36 5c 15 8b 6a c7 16 47 62 ...I=......$.Wz.....rn.6\..j..Gb
0a20 63 8d 18 83 d0 b1 15 bf 45 73 ac c3 48 f1 be f7 01 6d b5 a8 56 35 61 9c 0b a8 83 1c 1f 77 88 f0 c.......Es..H....m..V5a......w..
0a40 78 ff 00 51 8e e2 ba 2a c0 d0 3c 63 a5 78 8f 53 d5 f4 eb 23 32 dd 69 53 98 2e 12 64 db 92 09 1b x..Q...*..<c.x.S...#2.iS...d....
0a60 97 9e 46 54 8e c7 8e 40 c8 cf 11 f1 c6 39 75 7d 2b 42 f0 dd 84 4f 3e a9 7d a8 09 20 85 06 72 a8 ..FT...@.....9u}+B...O>.}.....r.
0a80 8c 18 93 d8 0d e0 e4 f1 80 4f 63 5e 99 a6 59 2e 9b a5 59 d8 2b b4 8b 6d 02 42 1d ba b0 55 03 27 .........Oc^..Y...Y.+..m.B...U.'
0aa0 f2 ac 7d 51 86 ab e2 ad 33 4a 40 1a 3b 13 fd a3 79 d7 03 86 48 50 f6 c9 72 ce 39 e3 c9 e9 c8 ae ..}Q....3J@.;...y...HP..r.9.....
0ac0 8a 8a 28 a2 b0 75 4d 2e e6 d7 50 7d 77 45 8d 5e fc c6 12 ea d5 9b 6a de c6 b9 da 33 d1 64 5c 9d ..(..uM...P}wE.^......j....3.d\.
0ae0 ac 78 e4 ab 70 41 5b 7a 4e bf 61 ac ef 8e de 46 8e ee 20 0c f6 73 ae c9 e0 24 74 74 3c 8f 63 c8 .x..pA[zN.a....F.....s...$tt<.c.
0b00 3d 41 23 9a af ae f8 4b 47 f1 28 db ab 43 73 71 11 00 18 45 ec c9 11 c1 c8 26 35 70 a4 e7 be 33 =A#....KG.(..Csq...E.....&5p...3
0b20 f9 55 3b 2f 0d 78 5f c1 36 ed 7b 6e ef a5 d9 c4 c5 9b cc d4 66 5b 70 cd f2 e5 91 9f 61 27 81 c8 .U;/.x_.6.{n........f[p.....a'..
0b40 eb 8e f8 a5 c4 de 2f db e7 5a cb 6f a0 86 cb 45 73 19 49 2f 88 3c 06 43 ca 45 91 9c 30 0c fd 08 ....../..Z.o...Es.I/.<.C.E..0...
0b60 0b 9d fd 35 14 55 3d 57 4c 83 58 d3 66 b1 b9 32 2a 49 82 1e 26 da f1 b0 20 ab ab 76 65 60 08 3d ...5.U=WL.X.f..2*I..&......ve`.=
0b80 88 15 8b 67 af 5c 68 a2 3b 0f 15 cb 1c 52 ee f2 e0 d4 c2 ec b7 ba 18 e0 b1 e9 14 9e aa d8 04 fd ...g.\h.;....R..................
0ba0 c2 7a 09 e7 f0 5e 81 3e b2 fa b8 b3 92 db 50 91 76 49 71 67 73 2d b3 48 33 93 bb cb 65 dd 92 07 .z...^.>......P.vIqgs-.H3...e...
0bc0 5c e7 03 d2 af 69 fa 16 9d a5 cc f3 db 40 c6 e5 d7 6b 5c cf 2b cd 33 2f 5d a6 47 25 b6 fb 67 02 \....i.......@...k\.+.3/].G%..g.
0be0 a8 6a 1e 23 32 4d 3e 99 e1 f4 8b 50 d5 93 e5 7f 98 f9 16 a7 38 cc ce 3a 11 ff 00 3c c7 ce 7d 00 .j.#2M>....P........8..:...<..}.
0c00 cb 0b da 1e 90 34 7b 16 8e 4b 99 2e ee e6 73 35 d5 d4 a0 06 9e 52 00 2d 81 c0 18 00 05 1c 2a a8 .....4{..K....s5.....R.-......*.
0c20 1d ab 4a 8a 28 a2 8a cf d5 34 2d 2f 5a 58 c6 a3 63 0d c3 45 9f 2a 46 5c 49 11 38 c9 47 1f 32 1e ..J.(....4-/ZX..c..E.*F\I.8.G.2.
0c40 07 2a 41 e2 a8 1f 07 e9 e5 81 17 ba e0 1d c0 d6 ae f9 fc e4 cd 4f 67 e1 6d 1a ca f1 6f 16 cc cf .*A..................Og.m...o...
0c60 76 87 31 dc de 4c f7 32 c7 c6 3e 57 95 99 94 7b 02 2b 62 8a 28 a2 9b 24 69 34 4f 14 a8 af 1b a9 v.1..L.2..>W...{.+b.(..$i4O.....
0c80 56 46 19 0c 0f 50 47 71 58 5f f0 86 68 b1 86 5b 48 ee ec 23 3c f9 5a 7d fc f6 b1 03 ea 23 8d d5 VF...PGqX_..h..[H..#<.Z}.....#..
0ca0 01 fc 29 3f e1 0d d2 1d 76 5c be a5 77 19 fb d1 5d 6a 77 33 46 fe cd 1b 48 55 87 b1 18 ad ab 5b ..)?....v\..w...]jw3F...HU.....[
0cc0 4b 6b 1b 58 ed 6c ed e2 b7 b7 8c 61 22 85 02 22 8f 40 07 02 a6 a2 8a 28 a2 8a 28 a2 8a 28 a2 8a Kk.X.l.....a"..".@.....(..(..(..
0ce0 28 a2 8a 28 a2 8a 28 a2 8a 28 a2 8a 28 a2 8a 28 a2 8a 28 af ff d9 (..(..(..(..(..(..(...
ref='/akkartik/mu/commit/412print-float-decimal.mu?h=hlt&id=a9e0cb7cc9da462c6e7886edfb554d7266e84c18'>a9e0cb7c ^
105f14f5 ^
a9e0cb7c ^
105f14f5 ^
a9e0cb7c ^

105f14f5 ^
a9e0cb7c ^
4a280280 ^

a9e0cb7c ^

4a280280 ^

a9e0cb7c ^


4a280280 ^
a9e0cb7c ^

4a280280 ^

a9e0cb7c ^


4a280280 ^


a9e0cb7c ^

4a280280 ^

a9e0cb7c ^


4a280280 ^




a9e0cb7c ^

4a280280 ^

a9e0cb7c ^


4a280280 ^


a9e0cb7c ^

4a280280 ^

a9e0cb7c ^


4a280280 ^

59007fb1 ^
a9e0cb7c ^

4a280280 ^

b6369d46 ^
a9e0cb7c ^







4a280280 ^
b6369d46 ^
4a280280 ^


a9e0cb7c ^
4a280280 ^




a9e0cb7c ^
4a280280 ^




a9e0cb7c ^
4a280280 ^




a9e0cb7c ^
4a280280 ^








a9e0cb7c ^
4a280280 ^







a9e0cb7c ^
4a280280 ^













4a280280 ^
4a280280 ^


4a280280 ^





4a280280 ^










4a280280 ^



a9e0cb7c ^
4a280280 ^




























































































































































































a9e0cb7c ^
4a280280 ^
4a280280 ^


a9e0cb7c ^
4a280280 ^




105f14f5 ^
a9e0cb7c ^
4a280280 ^




a9e0cb7c ^
4a280280 ^

e1eadf67 ^


4a280280 ^
e1eadf67 ^





4a280280 ^




a9e0cb7c ^
4a280280 ^


a9e0cb7c ^



4a280280 ^




a9e0cb7c ^
4a280280 ^









a9e0cb7c ^
4a280280 ^


a9e0cb7c ^


4a280280 ^



a9e0cb7c ^
4a280280 ^
a9e0cb7c ^
4a280280 ^

a9e0cb7c ^
b6369d46 ^






74f1512f ^
b6369d46 ^



74f1512f ^
b6369d46 ^



74f1512f ^
b6369d46 ^



74f1512f ^
b6369d46 ^







74f1512f ^
b6369d46 ^











































105f14f5 ^
b6369d46 ^


55dfa5b9 ^










b6369d46 ^
b6369d46 ^
55dfa5b9 ^
b6369d46 ^
55dfa5b9 ^

b6369d46 ^




55dfa5b9 ^
b6369d46 ^
6b1cde47 ^


4a280280 ^






cec5ef31 ^
4a280280 ^













74f1512f ^
4a280280 ^



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642























                                                                                    


                                                    

                                       

                                                                                    
        
                
                                          

                                                                                      
        
                
                                                 

                                                                                      
         
                
                                         

                                                                                        
                                           
                
                                               

                                                                                           
                                                                                          
                

                                             

                                                                                       


                                       


                                                    

                                        

                                                                                 
     
                
                                        

                                                                                 
      
                
                                          

                                                                                   
       
                
                                                 

                                                                                     
       
                
                                                  

                                                                                      
                                          
                
                                                  

                                                                                         
           
                

                                                                

                                                                                            

 


                                                    
                 

                                                                            

 


                                                       


                                                

                                                                                      

 


                                                    




                                                    

                                                                                  

 


                                                           


                                                    

                                                                                            

 


                                                      

                                                                                  
                                      

                                                                                      

 
                                                                                     







                                                                                       
                   
                                     


                 
                  




                          
                   




                          
                    




                          
                     








                                                     
                    







                                
                               













                                                                        
                                         


                                                                                           





                                              










                                                     



                  
                                                                 




























































































































































































                                                                                                       
                                                                                                                           
                                             


                 
                                                                                          




                               
               
                                                                                          




                 
                           

                          


                               
   





                    




                            
                                         


                                               



                                      




                  
                                                                                                                                                  









                                             
                                         


                                               


                                      



                  
                         
              
                             

 
                                                          






                                                                                    
                       



                          
                        



                          
                         



                          
                          







                                                     
                         











































                                                                        
               


                                             










                                
   
               
                       
   

                    




                                     
                       
   


               






                                                                                                        
              













                                             
                                



                                                                                                                     
# print out floats in decimal
# https://research.swtch.com/ftoa
#
# Basic idea:
#   Ignoring sign, floating point numbers are represented as 1.mantissa * 2^exponent
#   Therefore, to print a float in decimal, we need to:
#     - compute its value without decimal point
#     - convert to an array of decimal digits
#     - print out the array while inserting the decimal point appropriately
#
# Basic complication: the computation generates numbers larger than an int can
# hold. We need a way to represent big ints.
#
# Key insight: use a representation for big ints that's close to what we need
# anyway, an array of decimal digits.
#
# Style note: we aren't creating a big int library here. The only operations
# we need are halving and doubling. Following the link above, it seems more
# comprehensible to keep these operations inlined so that we can track the
# position of the decimal point with dispatch.
#
# This approach turns out to be fast enough for most purposes.
# Optimizations, however, get wildly more complex.

fn test-write-float-decimal-approximate-normal {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  # 0.5
  var half/xmm0: float <- rational 1, 2
  write-float-decimal-approximate s, half, 3
  check-stream-equal s, "0.5", "F - test-write-float-decimal-approximate-normal 0.5"
  # 0.25
  clear-stream s
  var quarter/xmm0: float <- rational 1, 4
  write-float-decimal-approximate s, quarter, 3
  check-stream-equal s, "0.25", "F - test-write-float-decimal-approximate-normal 0.25"
  # 0.75
  clear-stream s
  var three-quarters/xmm0: float <- rational 3, 4
  write-float-decimal-approximate s, three-quarters, 3
  check-stream-equal s, "0.75", "F - test-write-float-decimal-approximate-normal 0.75"
  # 0.125
  clear-stream s
  var eighth/xmm0: float <- rational 1, 8
  write-float-decimal-approximate s, eighth, 3
  check-stream-equal s, "0.125", "F - test-write-float-decimal-approximate-normal 0.125"
  # 0.0625; start using scientific notation
  clear-stream s
  var sixteenth/xmm0: float <- rational 1, 0x10
  write-float-decimal-approximate s, sixteenth, 3
  check-stream-equal s, "6.25e-2", "F - test-write-float-decimal-approximate-normal 0.0625"
  # sqrt(2); truncate floats with lots of digits after the decimal but not too many before
  clear-stream s
  var two-f/xmm0: float <- rational 2, 1
  var sqrt-2/xmm0: float <- square-root two-f
  write-float-decimal-approximate s, sqrt-2, 3
  check-stream-equal s, "1.414", "F - test-write-float-decimal-approximate-normal √2"
}

# print whole integers without decimals
fn test-write-float-decimal-approximate-integer {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  # 1
  var one-f/xmm0: float <- rational 1, 1
  write-float-decimal-approximate s, one-f, 3
  check-stream-equal s, "1", "F - test-write-float-decimal-approximate-integer 1"
  # 2
  clear-stream s
  var two-f/xmm0: float <- rational 2, 1
  write-float-decimal-approximate s, two-f, 3
  check-stream-equal s, "2", "F - test-write-float-decimal-approximate-integer 2"
  # 10
  clear-stream s
  var ten-f/xmm0: float <- rational 0xa, 1
  write-float-decimal-approximate s, ten-f, 3
  check-stream-equal s, "10", "F - test-write-float-decimal-approximate-integer 10"
  # -10
  clear-stream s
  var minus-ten-f/xmm0: float <- rational -0xa, 1
  write-float-decimal-approximate s, minus-ten-f, 3
  check-stream-equal s, "-10", "F - test-write-float-decimal-approximate-integer -10"
  # 999
  clear-stream s
  var minus-ten-f/xmm0: float <- rational 0x3e7, 1
  write-float-decimal-approximate s, minus-ten-f, 3
  check-stream-equal s, "999", "F - test-write-float-decimal-approximate-integer 1000"
  # 1000 - start using scientific notation
  clear-stream s
  var minus-ten-f/xmm0: float <- rational 0x3e8, 1
  write-float-decimal-approximate s, minus-ten-f, 3
  check-stream-equal s, "1.00e3", "F - test-write-float-decimal-approximate-integer 1000"
  # 100,000
  clear-stream s
  var hundred-thousand/eax: int <- copy 0x186a0
  var hundred-thousand-f/xmm0: float <- convert hundred-thousand
  write-float-decimal-approximate s, hundred-thousand-f, 3
  check-stream-equal s, "1.00e5", "F - test-write-float-decimal-approximate-integer 100,000"
}

fn test-write-float-decimal-approximate-zero {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  var zero: float
  write-float-decimal-approximate s, zero, 3
  check-stream-equal s, "0", "F - test-write-float-decimal-approximate-zero"
}

fn test-write-float-decimal-approximate-negative-zero {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  var n: int
  copy-to n, 0x80000000
  var negative-zero/xmm0: float <- reinterpret n
  write-float-decimal-approximate s, negative-zero, 3
  check-stream-equal s, "-0", "F - test-write-float-decimal-approximate-negative-zero"
}

fn test-write-float-decimal-approximate-infinity {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  var n: int
  #          0|11111111|00000000000000000000000
  #          0111|1111|1000|0000|0000|0000|0000|0000
  copy-to n, 0x7f800000
  var infinity/xmm0: float <- reinterpret n
  write-float-decimal-approximate s, infinity, 3
  check-stream-equal s, "Inf", "F - test-write-float-decimal-approximate-infinity"
}

fn test-write-float-decimal-approximate-negative-infinity {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  var n: int
  copy-to n, 0xff800000
  var negative-infinity/xmm0: float <- reinterpret n
  write-float-decimal-approximate s, negative-infinity, 3
  check-stream-equal s, "-Inf", "F - test-write-float-decimal-approximate-negative-infinity"
}

fn test-write-float-decimal-approximate-not-a-number {
  var s-storage: (stream byte 0x10)
  var s/ecx: (addr stream byte) <- address s-storage
  var n: int
  copy-to n, 0xffffffff  # exponent must be all 1's, and mantissa must be non-zero
  var nan/xmm0: float <- reinterpret n
  write-float-decimal-approximate s, nan, 3
  check-stream-equal s, "NaN", "F - test-write-float-decimal-approximate-not-a-number"
}

fn print-float-decimal-approximate screen: (addr screen), in: float, precision: int {
  var s-storage: (stream byte 0x10)
  var s/esi: (addr stream byte) <- address s-storage
  write-float-decimal-approximate s, in, precision
  print-stream screen, s
}

# 'precision' controls the maximum width past which we resort to scientific notation
fn write-float-decimal-approximate out: (addr stream byte), in: float, precision: int {
  # - special names
  var bits/eax: int <- reinterpret in
  compare bits, 0
  {
    break-if-!=
    write out, "0"
    return
  }
  compare bits, 0x80000000
  {
    break-if-!=
    write out, "-0"
    return
  }
  compare bits, 0x7f800000
  {
    break-if-!=
    write out, "Inf"
    return
  }
  compare bits, 0xff800000
  {
    break-if-!=
    write out, "-Inf"
    return
  }
  var exponent/ecx: int <- copy bits
  exponent <- shift-right 0x17  # 23 bits of mantissa
  exponent <- and 0xff
  exponent <- subtract 0x7f
  compare exponent, 0x80
  {
    break-if-!=
    write out, "NaN"
    return
  }
  # - regular numbers
  var sign/edx: int <- copy bits
  sign <- shift-right 0x1f
  {
    compare sign, 1
    break-if-!=
    append-byte out, 0x2d/minus
  }

  # v = 1.mantissa (in base 2) << 0x17
  var v/ebx: int <- copy bits
  v <- and 0x7fffff
  v <- or 0x00800000  # insert implicit 1
  # e = exponent - 0x17
  var e/ecx: int <- copy exponent
  e <- subtract 0x17  # move decimal place from before mantissa to after

  # initialize buffer with decimal representation of v
  # unlike https://research.swtch.com/ftoa, no ascii here
  var buf-storage: (array byte 0x7f)
  var buf/edi: (addr array byte) <- address buf-storage
  var n/eax: int <- decimal-digits v, buf
  # I suspect we can do without reversing, but we'll follow https://research.swtch.com/ftoa
  # closely for now.
  reverse-digits buf, n

  # loop if e > 0
  {
    compare e, 0
    break-if-<=
    n <- double-array-of-decimal-digits buf, n
    e <- decrement
    loop
  }

  var dp/edx: int <- copy n

  # loop if e < 0
  {
    compare e, 0
    break-if->=
    n, dp <- halve-array-of-decimal-digits buf, n, dp
    e <- increment
    loop
  }

  _write-float-array-of-decimal-digits out, buf, n, dp, precision
}

# store the decimal digits of 'n' into 'buf', units first
# n must be positive
fn decimal-digits n: int, _buf: (addr array byte) -> _/eax: int {
  var buf/edi: (addr array byte) <- copy _buf
  var i/ecx: int <- copy 0
  var curr/eax: int <- copy n
  var curr-byte/edx: int <- copy 0
  {
    compare curr, 0
    break-if-=
    curr, curr-byte <- integer-divide curr, 0xa
    var dest/ebx: (addr byte) <- index buf, i
    copy-byte-to *dest, curr-byte
    i <- increment
    loop
  }
  return i
}

fn reverse-digits _buf: (addr array byte), n: int {
  var buf/esi: (addr array byte) <- copy _buf
  var left/ecx: int <- copy 0
  var right/edx: int <- copy n
  right <- decrement
  {
    compare left, right
    break-if->=
    {
      var l-a/ecx: (addr byte) <- index buf, left
      var r-a/edx: (addr byte) <- index buf, right
      var l/ebx: byte <- copy-byte *l-a
      var r/eax: byte <- copy-byte *r-a
      copy-byte-to *l-a, r
      copy-byte-to *r-a, l
    }
    left <- increment
    right <- decrement
    loop
  }
}

# debug helper
fn dump-digits _buf: (addr array byte), count: int, msg: (addr array byte) {
  var buf/edi: (addr array byte) <- copy _buf
  var i/ecx: int <- copy 0
  print-string 0, msg
  print-string 0, ": "
  {
    compare i, count
    break-if->=
    var curr/edx: (addr byte) <- index buf, i
    var curr-byte/eax: byte <- copy-byte *curr
    var curr-int/eax: int <- copy curr-byte
    print-int32-decimal 0, curr-int
    print-string 0, " "
    break-if-=
    i <- increment
    loop
  }
  print-string 0, "\n"
}

fn double-array-of-decimal-digits _buf: (addr array byte), _n: int -> _/eax: int {
  var buf/edi: (addr array byte) <- copy _buf
  # initialize delta
  var delta/edx: int <- copy 0
  {
    var curr/ebx: (addr byte) <- index buf, 0
    var tmp/eax: byte <- copy-byte *curr
    compare tmp, 5
    break-if-<
    delta <- copy 1
  }
  # loop
  var x/eax: int <- copy 0
  var i/ecx: int <- copy _n
  i <- decrement
  {
    compare i, 0
    break-if-<=
    # x += 2*buf[i]
    {
      var tmp/ecx: (addr byte) <- index buf, i
      var tmp2/ecx: byte <- copy-byte *tmp
      x <- add tmp2
      x <- add tmp2
    }
    # x, buf[i+delta] = x/10, x%10
    {
      var dest-index/ecx: int <- copy i
      dest-index <- add delta
      var dest/edi: (addr byte) <- index buf, dest-index
      var next-digit/edx: int <- copy 0
      x, next-digit <- integer-divide x, 0xa
      copy-byte-to *dest, next-digit
    }
    #
    i <- decrement
    loop
  }
  # final patch-up
  var n/eax: int <- copy _n
  compare delta, 1
  {
    break-if-!=
    var curr/ebx: (addr byte) <- index buf, 0
    var one/edx: int <- copy 1
    copy-byte-to *curr, one
    n <- increment
  }
  return n
}

fn halve-array-of-decimal-digits _buf: (addr array byte), _n: int, _dp: int -> _/eax: int, _/edx: int {
  var buf/edi: (addr array byte) <- copy _buf
  var n/eax: int <- copy _n
  var dp/edx: int <- copy _dp
  # initialize one side
  {
    # if buf[n-1]%2 == 0, break
    var right-index/ecx: int <- copy n
    right-index <- decrement
    var right-a/ecx: (addr byte) <- index buf, right-index
    var right/ecx: byte <- copy-byte *right-a
    var right-int/ecx: int <- copy right
    var remainder/edx: int <- copy 0
    {
      var dummy/eax: int <- copy 0
      dummy, remainder <- integer-divide right-int, 2
    }
    compare remainder, 0
    break-if-=
    # buf[n] = 0
    var next-a/ecx: (addr byte) <- index buf, n
    var zero/edx: byte <- copy 0
    copy-byte-to *next-a, zero
    # n++
    n <- increment
  }
  # initialize the other
  var delta/ebx: int <- copy 0
  var x/esi: int <- copy 0
  {
    # if buf[0] >= 2, break
    var left/ecx: (addr byte) <- index buf, 0
    var src/ecx: byte <- copy-byte *left
    compare src, 2
    break-if->=
    # delta, x = 1, buf[0]
    delta <- copy 1
    x <- copy src
    # n--
    n <- decrement
    # dp--
    dp <- decrement
  }
  # loop
  var i/ecx: int <- copy 0
  {
    compare i, n
    break-if->=
    # x = x*10 + buf[i+delta]
    {
      var ten/edx: int <- copy 0xa
      x <- multiply ten
      var src-index/edx: int <- copy i
      src-index <- add delta
      var src-a/edx: (addr byte) <- index buf, src-index
      var src/edx: byte <- copy-byte *src-a
      x <- add src
    }
    # buf[i], x = x/2, x%2
    {
      var quotient/eax: int <- copy 0
      var remainder/edx: int <- copy 0
      quotient, remainder <- integer-divide x, 2
      x <- copy remainder
      var dest/edx: (addr byte) <- index buf, i
      copy-byte-to *dest, quotient
    }
    #
    i <- increment
    loop
  }
  return n, dp
}

fn _write-float-array-of-decimal-digits out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
  var buf/edi: (addr array byte) <- copy _buf
  {
    compare dp, 0
    break-if->=
    _write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
    return
  }
  {
    var dp2/eax: int <- copy dp
    compare dp2, precision
    break-if-<=
    _write-float-array-of-decimal-digits-in-scientific-notation out, buf, n, dp, precision
    return
  }
  {
    compare dp, 0
    break-if-!=
    append-byte out, 0x30/0
  }
  var i/eax: int <- copy 0
  # bounds = min(n, dp+3)
  var limit/edx: int <- copy dp
  limit <- add 3
  {
    compare limit, n
    break-if-<=
    limit <- copy n
  }
  {
    compare i, limit
    break-if->=
    # print '.' if necessary
    compare i, dp
    {
      break-if-!=
      append-byte out, 0x2e/decimal-point
    }
    var curr-a/ecx: (addr byte) <- index buf, i
    var curr/ecx: byte <- copy-byte *curr-a
    var curr-int/ecx: int <- copy curr
    curr-int <- add 0x30/0
    append-byte out, curr-int
    #
    i <- increment
    loop
  }
}

fn _write-float-array-of-decimal-digits-in-scientific-notation out: (addr stream byte), _buf: (addr array byte), n: int, dp: int, precision: int {
  var buf/edi: (addr array byte) <- copy _buf
  var i/eax: int <- copy 0
  {
    compare i, n
    break-if->=
    compare i, precision
    break-if->=
    compare i, 1
    {
      break-if-!=
      append-byte out, 0x2e/decimal-point
    }
    var curr-a/ecx: (addr byte) <- index buf, i
    var curr/ecx: byte <- copy-byte *curr-a
    var curr-int/ecx: int <- copy curr
    curr-int <- add 0x30/0
    append-byte out, curr-int
    #
    i <- increment
    loop
  }
  append-byte out, 0x65/e
  decrement dp
  write-int32-decimal out, dp
}

# follows the structure of write-float-decimal-approximate
# 'precision' controls the maximum width past which we resort to scientific notation
fn float-size in: float, precision: int -> _/eax: int {
  # - special names
  var bits/eax: int <- reinterpret in
  compare bits, 0
  {
    break-if-!=
    return 1  # for "0"
  }
  compare bits, 0x80000000
  {
    break-if-!=
    return 2  # for "-0"
  }
  compare bits, 0x7f800000
  {
    break-if-!=
    return 3  # for "Inf"
  }
  compare bits, 0xff800000
  {
    break-if-!=
    return 4  # for "-Inf"
  }
  var exponent/ecx: int <- copy bits
  exponent <- shift-right 0x17  # 23 bits of mantissa
  exponent <- and 0xff
  exponent <- subtract 0x7f
  compare exponent, 0x80
  {
    break-if-!=
    return 3  # for "NaN"
  }
  # - regular numbers
  # v = 1.mantissa (in base 2) << 0x17
  var v/ebx: int <- copy bits
  v <- and 0x7fffff
  v <- or 0x00800000  # insert implicit 1
  # e = exponent - 0x17
  var e/ecx: int <- copy exponent
  e <- subtract 0x17  # move decimal place from before mantissa to after

  # initialize buffer with decimal representation of v
  var buf-storage: (array byte 0x7f)
  var buf/edi: (addr array byte) <- address buf-storage
  var n/eax: int <- decimal-digits v, buf
  reverse-digits buf, n

  # loop if e > 0
  {
    compare e, 0
    break-if-<=
    n <- double-array-of-decimal-digits buf, n
    e <- decrement
    loop
  }

  var dp/edx: int <- copy n

  # loop if e < 0
  {
    compare e, 0
    break-if->=
    n, dp <- halve-array-of-decimal-digits buf, n, dp
    e <- increment
    loop
  }

  compare dp, 0
  {
    break-if->=
    return 8  # hacky for scientific notation
  }
  {
    var dp2/eax: int <- copy dp
    compare dp2, precision
    break-if-<=
    return 8  # hacky for scientific notation
  }

  # result = min(n, dp+3)
  var result/ecx: int <- copy dp
  result <- add 3
  {
    compare result, n
    break-if-<=
    result <- copy n
  }

  # account for decimal point
  compare dp, n
  {
    break-if->=
    result <- increment
  }

  # account for sign
  var sign/edx: int <- reinterpret in
  sign <- shift-right 0x1f
  {
    compare sign, 1
    break-if-!=
    result <- increment
  }
  return result
}

## helper

# like check-strings-equal, except array sizes don't have to match
fn check-buffer-contains _buf: (addr array byte), _contents: (addr array byte), msg: (addr array byte) {
  var buf/esi: (addr array byte) <- copy _buf
  var contents/edi: (addr array byte) <- copy _contents
  var a/eax: boolean <- string-starts-with? buf, contents
  check a, msg
  var len/ecx: int <- length contents
  var len2/eax: int <- length buf
  compare len, len2
  break-if-=
  var c/eax: (addr byte) <- index buf, len
  var d/eax: byte <- copy-byte *c
  var e/eax: int <- copy d
  check-ints-equal e, 0, msg
}

fn test-check-buffer-contains {
  var arr: (array byte 4)
  var a/esi: (addr array byte) <- address arr
  var b/eax: (addr byte) <- index a, 0
  var c/ecx: byte <- copy 0x61/a
  copy-byte-to *b, c
  check-buffer-contains a, "a", "F - test-check-buffer-contains"
  check-buffer-contains "a", "a", "F - test-check-buffer-contains/null"  # no null check when arrays have same length
}