float-formats 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +27 -32
- data/Manifest.txt +10 -18
- data/README.txt +330 -327
- data/Rakefile +38 -4
- data/lib/float-formats.rb +9 -9
- data/lib/float-formats/bytes.rb +463 -303
- data/lib/float-formats/classes.rb +1950 -1605
- data/lib/float-formats/formats.rb +633 -669
- data/lib/float-formats/native.rb +144 -272
- data/lib/float-formats/version.rb +4 -4
- data/tasks/ann.rake +80 -0
- data/tasks/bones.rake +20 -0
- data/tasks/gem.rake +192 -0
- data/tasks/git.rake +40 -0
- data/tasks/manifest.rake +48 -0
- data/tasks/notes.rake +27 -0
- data/tasks/post_load.rake +39 -0
- data/tasks/rdoc.rake +50 -0
- data/tasks/rubyforge.rake +55 -0
- data/tasks/setup.rb +279 -0
- data/tasks/spec.rake +54 -0
- data/tasks/svn.rake +47 -0
- data/tasks/test.rake +40 -0
- data/test/gen_test_data.rb +119 -119
- data/test/test_arithmetic.rb +36 -0
- data/test/test_bytes.rb +43 -0
- data/test/test_data.yaml +1667 -1667
- data/test/test_float_formats.rb +208 -0
- data/test/test_helper.rb +2 -1
- data/test/test_native-float.rb +84 -77
- metadata +123 -60
- data/config/hoe.rb +0 -73
- data/config/requirements.rb +0 -17
- data/script/destroy +0 -14
- data/script/destroy.cmd +0 -1
- data/script/generate +0 -14
- data/script/generate.cmd +0 -1
- data/script/txt2html +0 -74
- data/script/txt2html.cmd +0 -1
- data/tasks/deployment.rake +0 -34
- data/tasks/environment.rake +0 -7
- data/tasks/website.rake +0 -17
- data/test/test_float-formats.rb +0 -169
@@ -1,669 +1,633 @@
|
|
1
|
-
# Float-Formats
|
2
|
-
# Definition of common floating-point formats
|
3
|
-
|
4
|
-
require 'nio'
|
5
|
-
require 'nio/sugar'
|
6
|
-
|
7
|
-
require 'enumerator'
|
8
|
-
|
9
|
-
require 'float-formats/classes.rb'
|
10
|
-
|
11
|
-
|
12
|
-
module
|
13
|
-
|
14
|
-
|
15
|
-
# Floating Point Format Definitions ==========================================
|
16
|
-
|
17
|
-
# Helper methods to define IEEE 754r formats
|
18
|
-
module IEEE
|
19
|
-
# Define an IEEE binary format by passing parameters in a hash;
|
20
|
-
# :significand and :exponent are used to defined the fields,
|
21
|
-
# optional parameters may follow.
|
22
|
-
def self.binary(parameters)
|
23
|
-
significand_bits = parameters[:significand]
|
24
|
-
exponent_bits = parameters[:exponent]
|
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
|
-
decimal({
|
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
|
-
VAX_D
|
192
|
-
:fields=>[:significand, 55, :exponent, 8, :sign, 1],
|
193
|
-
:bias=>128, :bias_mode=>:fractional_significand,
|
194
|
-
:hidden_bit=>true,
|
195
|
-
:endianness=>:little_big_endian,
|
196
|
-
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
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
|
-
e =
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
e
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
m
|
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
|
-
s
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
e
|
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
|
-
:fields=>[:exponent_sign, 2, :significand,12],
|
635
|
-
:endiannes=>:big_endian,
|
636
|
-
:bias=>64, :bias_mode=>:fractional_significand,
|
637
|
-
:zero_encoded_exp=>0, :min_encoded_exp=>0,:max_encoded_exp=>127
|
638
|
-
)
|
639
|
-
|
640
|
-
=begin
|
641
|
-
# Note:
|
642
|
-
# One could be tempted to define a double-double type as:
|
643
|
-
IEEE_DOUBLE_DOUBLE = BinaryFormat.new(
|
644
|
-
:fields=>[:significand,52,:lo_exponent,11,:lo_sign,1,:significand,52,:exponent,11,:sign,1],
|
645
|
-
:fields_handler=>lambda{|fields|
|
646
|
-
fields[2] = fields[5];
|
647
|
-
bits,max_exp = 53,2047
|
648
|
-
if fields[4]>bits && fields[4]<max_exp
|
649
|
-
fields[1] = fields[4] - bits
|
650
|
-
else # 0, denormals, small numbers, NaN, Infinities
|
651
|
-
fields[0] = fields[1] = 0
|
652
|
-
end
|
653
|
-
},
|
654
|
-
:bias=>1023, :bias_mode=>:normalized_significand,
|
655
|
-
:hidden_bit=>true,
|
656
|
-
:endianness=>:little_endian, :round=>:even,
|
657
|
-
:gradual_underflow=>true, :infinity=>true, :nan=>true
|
658
|
-
)
|
659
|
-
# But this is incorrect since there's a hidden bit in the low double too and it must be normalized.
|
660
|
-
# In general the halfs of the significand need not be adjacent, they
|
661
|
-
# can have exponets with a separation higher than 53; (in fact the minimum separation seems to be 54)
|
662
|
-
# and they can have different sings, too;
|
663
|
-
# double-double is too tricky to be supported by this package.
|
664
|
-
=end
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
end
|
669
|
-
|
1
|
+
# Float-Formats
|
2
|
+
# Definition of common floating-point formats
|
3
|
+
|
4
|
+
require 'nio'
|
5
|
+
require 'nio/sugar'
|
6
|
+
|
7
|
+
require 'enumerator'
|
8
|
+
|
9
|
+
require 'float-formats/classes.rb'
|
10
|
+
|
11
|
+
|
12
|
+
module Flt
|
13
|
+
|
14
|
+
|
15
|
+
# Floating Point Format Definitions ==========================================
|
16
|
+
|
17
|
+
# Helper methods to define IEEE 754r formats
|
18
|
+
module IEEE
|
19
|
+
# Define an IEEE binary format by passing parameters in a hash;
|
20
|
+
# :significand and :exponent are used to defined the fields,
|
21
|
+
# optional parameters may follow.
|
22
|
+
def self.binary(name, parameters)
|
23
|
+
significand_bits = parameters[:significand]
|
24
|
+
exponent_bits = parameters[:exponent]
|
25
|
+
Flt.define(name,{
|
26
|
+
:base=>BinaryFormat,
|
27
|
+
:fields=>[:significand,significand_bits,:exponent,exponent_bits,:sign,1],
|
28
|
+
:bias=>2**(exponent_bits-1)-1, :bias_mode=>:scientific_significand,
|
29
|
+
:hidden_bit=>true,
|
30
|
+
:endianness=>:little_endian, :round=>:half_even,
|
31
|
+
:gradual_underflow=>true, :infinity=>true, :nan=>true
|
32
|
+
}.merge(parameters))
|
33
|
+
end
|
34
|
+
|
35
|
+
# Define an IEEE binary interchange format given its width in bits
|
36
|
+
def self.interchange_binary(name,width_in_bits, options={})
|
37
|
+
raise "Invalid IEEE binary interchange format definition: size (#{width_in_bits}) is not valid" unless (width_in_bits%32)==0 && (width_in_bits/32)>=4
|
38
|
+
p = width_in_bits - (4*Math.log(width_in_bits)/Math.log(2)).round.to_i + 13
|
39
|
+
binary(name,{:significand=>p-1, :exponent=>width_in_bits-p}.merge(options))
|
40
|
+
end
|
41
|
+
|
42
|
+
# Define an IEEE decimal format by passing parameters in a hash;
|
43
|
+
# :significand and :exponent are used to defined the fields,
|
44
|
+
# optional parameters may follow.
|
45
|
+
def self.decimal(name,parameters)
|
46
|
+
significand_continuation_bits = parameters[:significand]
|
47
|
+
exponent_continuation_bits = parameters[:exponent]
|
48
|
+
Flt.define(name,{
|
49
|
+
:base=>DPDFormat,
|
50
|
+
:fields=>[:significand_continuation,significand_continuation_bits,:exponent_continuation,exponent_continuation_bits,:combination,5,:sign,1],
|
51
|
+
:normalized=>false,
|
52
|
+
:endianness=>:big_endian,
|
53
|
+
:gradual_underflow=>true, :infinity=>true, :nan=>true,
|
54
|
+
:round=>:half_even
|
55
|
+
}.merge(parameters))
|
56
|
+
end
|
57
|
+
|
58
|
+
# Define an IEEE decimal interchange format given its width in bits
|
59
|
+
def self.interchange_decimal(name,width_in_bits, options={})
|
60
|
+
raise "Invalid IEEE decimal interchange format definition: size (#{width_in_bits}) is not valid" unless (width_in_bits%32)==0
|
61
|
+
p = width_in_bits*9/32 - 2
|
62
|
+
t = (p-1)*10/3
|
63
|
+
w = width_in_bits - t - 6
|
64
|
+
decimal(name,{:significand=>t, :exponent=>w}.merge(options))
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
# IEEE 754 binary types, as stored in little endian architectures such as Intel, Alpha
|
70
|
+
|
71
|
+
IEEE.binary :IEEE_binary16, :significand=>10, :exponent=>5
|
72
|
+
IEEE.binary :IEEE_binary32, :significand=>23,:exponent=>8
|
73
|
+
IEEE.binary :IEEE_binary64, :significand=>52,:exponent=>11
|
74
|
+
IEEE.binary :IEEE_binary80, :significand=>64,:exponent=>15, :hidden_bit=>false, :min_encoded_exp=>1
|
75
|
+
IEEE.binary :IEEE_binary128, :significand=>112,:exponent=>15
|
76
|
+
|
77
|
+
|
78
|
+
# IEEE 754 in big endian order (SPARC, Motorola 68k, PowerPC)
|
79
|
+
|
80
|
+
IEEE.binary :IEEE_binary16_BE, :significand=>10, :exponent=>5, :endianness=>:big_endian
|
81
|
+
IEEE.binary :IEEE_binary32_BE, :significand=>23,:exponent=>8, :endianness=>:big_endian
|
82
|
+
IEEE.binary :IEEE_binary64_BE, :significand=>52,:exponent=>11, :endianness=>:big_endian
|
83
|
+
IEEE.binary :IEEE_binary80_BE, :significand=>64,:exponent=>15, :endianness=>:big_endian, :hidden_bit=>false, :min_encoded_exp=>1
|
84
|
+
IEEE.binary :IEEE_binary128_BE, :significand=>112,:exponent=>15, :endianness=>:big_endian
|
85
|
+
|
86
|
+
|
87
|
+
# some IEEE745r interchange binary formats
|
88
|
+
|
89
|
+
IEEE.interchange_binary :IEEE_binary256, 256
|
90
|
+
IEEE.interchange_binary :IEEE_binary512, 512
|
91
|
+
IEEE.interchange_binary :IEEE_binary1024, 1024
|
92
|
+
IEEE.interchange_binary :IEEE_binary256_BE, 256, :endianness=>:big_endian
|
93
|
+
IEEE.interchange_binary :IEEE_binary512_BE, 512, :endianness=>:big_endian
|
94
|
+
IEEE.interchange_binary :IEEE_binary1024_BE, 1024, :endianness=>:big_endian
|
95
|
+
|
96
|
+
|
97
|
+
# old names
|
98
|
+
IEEE_binaryx = IEEE_binary80
|
99
|
+
IEEE_HALF = IEEE_binary16
|
100
|
+
IEEE_SINGLE = IEEE_binary32
|
101
|
+
IEEE_DOUBLE = IEEE_binary64
|
102
|
+
IEEE_EXTENDED = IEEE_binary80
|
103
|
+
IEEE_QUAD = IEEE_binary128
|
104
|
+
IEEE_128 = IEEE_binary128
|
105
|
+
IEEE_H_BE = IEEE_binary16_BE
|
106
|
+
IEEE_S_BE = IEEE_binary32_BE
|
107
|
+
IEEE_D_BE = IEEE_binary64_BE
|
108
|
+
IEEE_X_BE = IEEE_binary80_BE
|
109
|
+
IEEE_128_BE = IEEE_binary128_BE
|
110
|
+
IEEE_Q_BE = IEEE_binary128_BE
|
111
|
+
|
112
|
+
|
113
|
+
# Decimal IEEE 754r formats
|
114
|
+
|
115
|
+
IEEE.decimal :IEEE_decimal32, :significand=>20, :exponent=>6
|
116
|
+
IEEE.decimal :IEEE_decimal64, :significand=>50, :exponent=>8
|
117
|
+
IEEE.decimal :IEEE_decimal128, :significand=>110, :exponent=>12
|
118
|
+
|
119
|
+
# some IEEE745r interchange binary formats
|
120
|
+
|
121
|
+
IEEE.interchange_decimal :IEEE_decimal96, 96
|
122
|
+
IEEE.interchange_decimal :IEEE_decimal192, 192
|
123
|
+
IEEE.interchange_decimal :IEEE_decimal256, 256
|
124
|
+
|
125
|
+
# old names
|
126
|
+
|
127
|
+
IEEE_DEC32 = IEEE_decimal32
|
128
|
+
IEEE_DEC64 = IEEE_decimal64
|
129
|
+
IEEE_DEC128 = IEEE_decimal128
|
130
|
+
|
131
|
+
# Excess 128 used by Microsoft Basic in 8-bit micros, Spectrum, ...
|
132
|
+
|
133
|
+
Flt.define BinaryFormat, :XS128,
|
134
|
+
:fields=>[:significand,31,:sign,1,:exponent,8],
|
135
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
136
|
+
:hidden_bit=>true,
|
137
|
+
:endianness=>:big_endian, :round=>:half_up,
|
138
|
+
:endianness=>:big_endian,
|
139
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
140
|
+
|
141
|
+
# HP-3000 excess 256 format, HP-Tandem...
|
142
|
+
|
143
|
+
Flt.define BinaryFormat, :XS256,
|
144
|
+
:fields=>[:significand,22,:exponent,9,:sign,1],
|
145
|
+
:bias=>256, :bias_mode=>:scientific_significand,
|
146
|
+
:hidden_bit=>true, :min_encoded_exp=>0,
|
147
|
+
:endianness=>:big_endian, :round=>:half_up,
|
148
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
149
|
+
|
150
|
+
Flt.define :XS256_DOUBLE, BinaryFormat,
|
151
|
+
:fields=>[:significand,54,:exponent,9,:sign,1],
|
152
|
+
:bias=>256, :bias_mode=>:scientific_significand,
|
153
|
+
:hidden_bit=>true, :min_encoded_exp=>0,
|
154
|
+
:endianness=>:big_endian, :round=>:half_up,
|
155
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
156
|
+
|
157
|
+
# Borland Pascal 48 bits "Real" Format
|
158
|
+
|
159
|
+
Flt.define :BORLAND48, BinaryFormat,
|
160
|
+
:fields=>[:exponent,8,:significand,39,:sign,1],
|
161
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
162
|
+
:hidden_bit=>true,
|
163
|
+
:endianness=>:little_endian,
|
164
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
165
|
+
|
166
|
+
# Microsoft Binary Floating-point (Quickbasic)
|
167
|
+
|
168
|
+
Flt.define :MBF_SINGLE, BinaryFormat,
|
169
|
+
:fields=>[:significand,23,:sign,1,:exponent,8],
|
170
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
171
|
+
:hidden_bit=>true,
|
172
|
+
:endianness=>:little_endian,
|
173
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
174
|
+
|
175
|
+
Flt.define :MBF_DOUBLE, BinaryFormat,
|
176
|
+
:fields=>[:significand,55,:sign,1,:exponent,8],
|
177
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
178
|
+
:hidden_bit=>true,
|
179
|
+
:endianness=>:little_endian,
|
180
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
181
|
+
|
182
|
+
# DEC formats (VAX)
|
183
|
+
|
184
|
+
Flt.define :VAX_F, BinaryFormat,
|
185
|
+
:fields=>[:significand, 23, :exponent, 8, :sign, 1],
|
186
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
187
|
+
:hidden_bit=>true,
|
188
|
+
:endianness=>:little_big_endian,
|
189
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
190
|
+
|
191
|
+
Flt.define :VAX_D, BinaryFormat,
|
192
|
+
:fields=>[:significand, 55, :exponent, 8, :sign, 1],
|
193
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
194
|
+
:hidden_bit=>true,
|
195
|
+
:endianness=>:little_big_endian,
|
196
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
197
|
+
|
198
|
+
Flt.define :VAX_G, BinaryFormat,
|
199
|
+
:fields=>[:significand, 52, :exponent, 11, :sign, 1],
|
200
|
+
:bias=>1024, :bias_mode=>:fractional_significand,
|
201
|
+
:hidden_bit=>true,
|
202
|
+
:endianness=>:little_big_endian,
|
203
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
204
|
+
|
205
|
+
Flt.define :VAX_H, BinaryFormat,
|
206
|
+
:fields=>[:significand, 112, :exponent, 15, :sign, 1],
|
207
|
+
:bias=>16384, :bias_mode=>:fractional_significand,
|
208
|
+
:hidden_bit=>true,
|
209
|
+
:endianness=>:little_big_endian,
|
210
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
211
|
+
|
212
|
+
# DEC PDP 11 variants (minimum exponent used for normalized values other than zero)
|
213
|
+
|
214
|
+
Flt.define :PDP11_F, BinaryFormat,
|
215
|
+
:fields=>[:significand, 23, :exponent, 8, :sign, 1],
|
216
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
217
|
+
:hidden_bit=>true, :min_encoded_exp=>0,
|
218
|
+
:endianness=>:little_big_endian,
|
219
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
220
|
+
|
221
|
+
Flt.define :PDP11_D, BinaryFormat,
|
222
|
+
:fields=>[:significand, 55, :exponent, 8, :sign, 1],
|
223
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
224
|
+
:hidden_bit=>true, :min_encoded_exp=>0,
|
225
|
+
:endianness=>:little_big_endian,
|
226
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
227
|
+
|
228
|
+
|
229
|
+
# Format used in HP Saturn-based RPL calculators (HP48,HP49,HP50, also HP32s, HP42s --which use RPL internally)
|
230
|
+
# (these formats are not used in the HP-71B which is a Saturn, non-RPL machine)
|
231
|
+
|
232
|
+
Flt.define :SATURN, BCDFormat,
|
233
|
+
:fields=>[:prolog,5,:exponent,3,:significand,12,:sign,1],
|
234
|
+
:fields_handler=>lambda{|fields| fields[0]=2933},
|
235
|
+
:exponent_mode=>:radix_complement,
|
236
|
+
:endianness=>:little_endian, :round=>:half_even,
|
237
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
238
|
+
|
239
|
+
Flt.define :SATURN_X, BCDFormat,
|
240
|
+
:fields=>[:prolog,5,:exponent,5,:significand,15,:sign,1],
|
241
|
+
:fields_handler=>lambda{|fields| fields[0]=2955},
|
242
|
+
:exponent_mode=>:radix_complement,
|
243
|
+
:endianness=>:little_endian, :round=>:half_even,
|
244
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
245
|
+
|
246
|
+
|
247
|
+
RPL = SATURN
|
248
|
+
RPL_X = SATURN_X
|
249
|
+
|
250
|
+
# SATURN HP-71B (IEEE, NON-RPL) formats
|
251
|
+
|
252
|
+
# HP-71B REAL format (12-form) which is stored in a single register
|
253
|
+
Flt.define :HP71B, BCDFormat,
|
254
|
+
:fields=>[:exponent,3,:significand,12,:sign,1],
|
255
|
+
:exponent_mode=>:radix_complement,
|
256
|
+
:endianness=>:little_endian, :round=>:half_even,
|
257
|
+
:gradual_underflow=>true, :infinity=>true, :nan=>true,
|
258
|
+
:denormal_encoded_exp=>501,
|
259
|
+
:nan_encoded_exp=>"F01", # signaling NaN is F02
|
260
|
+
:infinite_encoded_exp=>"F00"
|
261
|
+
|
262
|
+
# HP-71B internal 15-digit format (15-form), stored in a pair of registers
|
263
|
+
# we use here a little-endian order for the registers, otherwise the
|
264
|
+
# definition would be [:significand,15,:unused1,1,:exponent,5,:unused2,10,:sign,1]
|
265
|
+
Flt.define :HP71B_X, BCDFormat,
|
266
|
+
:fields=>[:exponent,5,:unused2,10,:sign,1, :significand,15,:unused1,1],
|
267
|
+
:exponent_mode=>:radix_complement,
|
268
|
+
:endianness=>:little_endian, :round=>:half_even,
|
269
|
+
:gradual_underflow=>false, :infinity=>true, :nan=>true,
|
270
|
+
:nan_encoded_exp=>"00F01",
|
271
|
+
:infinite_encoded_exp=>"00F00"
|
272
|
+
|
273
|
+
# Format used in classic HP calculators (HP-35, ... HP-15C)
|
274
|
+
# Endianness is indeterminate, since these machines have named registers that
|
275
|
+
# hold a floating-point value in a single 56-bit word.
|
276
|
+
# (But intra-word field/nibble addressing is little-endian)
|
277
|
+
Flt.define :HP_CLASSIC, BCDFormat,
|
278
|
+
:fields=>[:exponent,3,:significand,10,:sign,1],
|
279
|
+
:exponent_mode=>:radix_complement,
|
280
|
+
:min_exp=>-99, :max_exp=>99, # the most significant nibble of exponent if for sign only
|
281
|
+
:endianness=>:big_endian, :round=>:half_up,
|
282
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
283
|
+
|
284
|
+
|
285
|
+
# IBM Floating Point Architecture (IBM 360,370, DG Eclipse, ...)
|
286
|
+
|
287
|
+
# short
|
288
|
+
Flt.define :IBM32, HexadecimalFormat,
|
289
|
+
:fields=>[:significand,24,:exponent,7,:sign,1],
|
290
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
291
|
+
:endianness=>:big_endian
|
292
|
+
|
293
|
+
# long
|
294
|
+
Flt.define :IBM64, HexadecimalFormat,
|
295
|
+
:fields=>[:significand,56,:exponent,7,:sign,1],
|
296
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
297
|
+
:endianness=>:big_endian
|
298
|
+
|
299
|
+
# extended: two long values pasted together
|
300
|
+
Flt.define :IBM128, HexadecimalFormat,
|
301
|
+
:fields=>[:significand,14*4,:lo_exponent,7,:lo_sign,1,:significand,14*4,:exponent,7,:sign,1],
|
302
|
+
:fields_handler=>lambda{|fields| fields[1]=(fields[4]>=14&&fields[4]<127) ? fields[4]-14 : fields[4];fields[2]=fields[5] },
|
303
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
304
|
+
:min_encoded_exp=>14, # to avoid out-of-range exponents in the lower half
|
305
|
+
:endianness=>:big_endian
|
306
|
+
|
307
|
+
# It think this has never been used:
|
308
|
+
Flt.define :IBMX, HexadecimalFormat,
|
309
|
+
:fields=>[:significand,14*4,:exponent,7,:unused_sign,1,:significand,14*4,:exponent,7,:sign,1],
|
310
|
+
:fields_handler=>lambda{|fields| fields[2]=0},
|
311
|
+
:bias=>8192, :bias_mode=>:fractional_significand,
|
312
|
+
:endianness=>:big_endian
|
313
|
+
|
314
|
+
# Cray-1
|
315
|
+
Flt.define :CRAY, BinaryFormat,
|
316
|
+
:fields=>[:significand,48,:exponent,15,:sign,1],
|
317
|
+
:bias=>16384, :bias_mode=>:fractional_significand,
|
318
|
+
:hidden_bit=>false,
|
319
|
+
:min_encoded_exp=>8192, :max_encoded_exp=>24575, :zero_encoded_exp=>0,
|
320
|
+
:endianness=>:big_endian,
|
321
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
322
|
+
|
323
|
+
# CDC 6600/7600
|
324
|
+
# Byte endianness is arbitrary, since these machines were word-addressable, in 60-bit words,
|
325
|
+
# but the two words used in double precision numbers are in big endian order
|
326
|
+
# TO DO: apply this:
|
327
|
+
# The exponent encoded value 1023 is used for NaN
|
328
|
+
# The exponent encoded value 0 is used for underflow
|
329
|
+
# The exponent encoded value 2047 is used for overflow
|
330
|
+
#
|
331
|
+
# The exponent needs special treatment, because instead of excess encoding, which is equivalent to two's complement followed
|
332
|
+
# by sign bit reversal, one's complement followed by sign bit reversal is used, which is equivalent
|
333
|
+
# to use a bias diminished by one for negative exponents. Note that the exponent encoded value that equals the bias is
|
334
|
+
# not used (is used as a NaN indicator)
|
335
|
+
class CDCFormat < BinaryFormat # :nodoc:
|
336
|
+
def self.encode_exponent(e,mode)
|
337
|
+
ee = super
|
338
|
+
ee -= 1 if e<0
|
339
|
+
ee
|
340
|
+
end
|
341
|
+
def self.decode_exponent(ee,mode)
|
342
|
+
e = super
|
343
|
+
e += 1 if e<0
|
344
|
+
e
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
Flt.define :CDC_SINGLE, CDCFormat,
|
349
|
+
:fields=>[:significand,48, :exponent,11, :sign,1],
|
350
|
+
:bias=>1024, :bias_mode=>:integral_significand,
|
351
|
+
:min_exp=>-1023,
|
352
|
+
:neg_mode=>:diminished_radix_complement,
|
353
|
+
:hidden_bit=>false,
|
354
|
+
:endianess=>:big_endian,
|
355
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
356
|
+
|
357
|
+
# The CDC_DOUBLE can be splitted in two CDC_SINGLE values:
|
358
|
+
# get_bitfields(v,[CDC_SINGLE.total_bits]*2,CDC_DOUBLE.endianness).collect{|x| int_to_bytes(x,0,CDC_SINGLE.endianness)}
|
359
|
+
# and the value of the double is the sum of the values of the singles.
|
360
|
+
# Unlike the single, we must use :fractional_significand mode because with :integral_significand
|
361
|
+
# the exponent would refer to the whole significand, but it must refer only to the most significant half.
|
362
|
+
# we substract the number of bits in the single to the bias and exponent because of this change,
|
363
|
+
# and add 48 to the min_exponent to avoid the exponent of the low order single to be out of range
|
364
|
+
# because the exponent of the low order single is adjusted to
|
365
|
+
# the position of its digits by substracting 48 from the high order exponent
|
366
|
+
# when its exponent would be out of range
|
367
|
+
# Note that when computing the low order exponent with the fields handler we must take into account the sign
|
368
|
+
# because for negative numbers all the fields are one-complemented.
|
369
|
+
Flt.define :CDC_DOUBLE, CDCFormat,
|
370
|
+
:fields=>[:significand,48,:lo_exponent,11,:lo_sign,1,:significand,48,:exponent,11,:sign,1],
|
371
|
+
:fields_handler=>lambda{|fields|
|
372
|
+
fields[1]=(fields[4]>0&&fields[4]<2047) ? fields[4]-((-1)**fields[5])*48 : fields[4]
|
373
|
+
fields[2]=fields[5]
|
374
|
+
},
|
375
|
+
:bias=>1024-48, :bias_mode=>:fractional_significand,
|
376
|
+
:min_encoded_exp=>48+1, # + 1 because the bias for negative is 1023
|
377
|
+
:neg_mode=>:diminished_radix_complement,
|
378
|
+
:hidden_bit=>false,
|
379
|
+
:endianess=>:big_endian,
|
380
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
381
|
+
|
382
|
+
|
383
|
+
# Univac 1100
|
384
|
+
# Byte endianness is arbitrary, since these machines were word-addressable, in 36-bit words,
|
385
|
+
# but the two words used in double precision numbers are in big endian order
|
386
|
+
Flt.define :UNIVAC_SINGLE, BinaryFormat,
|
387
|
+
:fields=>[:significand,27, :exponent,8, :sign,1],
|
388
|
+
:bias=>128, :bias_mode=>:fractional_significand,
|
389
|
+
:neg_mode=>:diminished_radix_complement,
|
390
|
+
:hidden_bit=>false,
|
391
|
+
:endianess=>:big_endian,
|
392
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
393
|
+
|
394
|
+
Flt.define :UNIVAC_DOUBLE, BinaryFormat,
|
395
|
+
:fields=>[:significand,60, :exponent,11, :sign,1],
|
396
|
+
:bias=>1024, :bias_mode=>:fractional_significand,
|
397
|
+
:neg_mode=>:diminished_radix_complement,
|
398
|
+
:hidden_bit=>false,
|
399
|
+
:endianess=>:big_endian,
|
400
|
+
:gradual_underflow=>false, :infinity=>false, :nan=>false
|
401
|
+
|
402
|
+
|
403
|
+
# :stopdoc: # the next definition is not handled correctly by RDoc
|
404
|
+
Flt.define(:APPLE_INSANE,BinaryFormat,
|
405
|
+
:fields=>[:significand,23,:sign,1,:exponent,8],
|
406
|
+
:bias=>128, :bias_mode=>:scientific_significand,
|
407
|
+
:hidden_bit=>false, :min_encoded_exp=>0,
|
408
|
+
:neg_mode=>:radix_complement_significand,
|
409
|
+
:endianness=>:big_endian,
|
410
|
+
:gradual_underflow=>true, :infinity=>false, :nan=>false) { |fp|
|
411
|
+
# This needs a peculiar treatment for the negative values, which not simply use two's complement
|
412
|
+
# but also avoid having the sign and msb of the significand equal.
|
413
|
+
# Note that here we have a separate sign bit, but it can also be considered as the msb of the significand
|
414
|
+
# in two's complement, in which case the radix point is after the two msbs, which are the ones that
|
415
|
+
# should not be equal. (except for zero and other values using the minimum exponent).
|
416
|
+
def fp.neg_significand_exponent(s,f,e)
|
417
|
+
#puts "before: #{s} #{f.to_s(16)}"
|
418
|
+
f,e = super
|
419
|
+
s = (s+1)%2
|
420
|
+
#print "minus #{f.to_s(16)}"
|
421
|
+
if e>@zero_encoded_exp && f==0
|
422
|
+
f = 1<<(significand_digits-1)
|
423
|
+
e += 1
|
424
|
+
else
|
425
|
+
while (e>@zero_encoded_exp) && (f>>(significand_digits-1))&1 == s
|
426
|
+
e -= 1
|
427
|
+
f = (f << 1) & (radix_power(significand_digits)-1)
|
428
|
+
#print " << "
|
429
|
+
end
|
430
|
+
end
|
431
|
+
#puts ""
|
432
|
+
[f,e]
|
433
|
+
end
|
434
|
+
}
|
435
|
+
# :startdoc:
|
436
|
+
|
437
|
+
|
438
|
+
# Sofware floating point implementatin for the Apple II (6502)
|
439
|
+
# the significand & sign are a single field in two's commplement
|
440
|
+
APPLE = APPLE_INSANE
|
441
|
+
|
442
|
+
# Wang 2200 Basic Decimal floating point
|
443
|
+
Flt.define(:WANG2200,BCDFormat,
|
444
|
+
:fields=>[:significand,13,:exponent,2,:signs,1],
|
445
|
+
:endiannes=>:big_endian,
|
446
|
+
:bias_mode=>:scientific_significand,
|
447
|
+
:min_exp=>-99, :max_exp=>99,
|
448
|
+
:zero_encoded_exp=>0, :min_encoded_exp=>0
|
449
|
+
) { |wang2200|
|
450
|
+
|
451
|
+
# needs special handling because significand and exponent are both stored
|
452
|
+
# as sign-magnitude, with both signs combined in a single nibble (decimal digit)
|
453
|
+
def wang2200.unpack(v)
|
454
|
+
f = unpack_fields_hash(v)
|
455
|
+
m = f[:significand]
|
456
|
+
e = f[:exponent]
|
457
|
+
ss = f[:signs]
|
458
|
+
s = (ss==9 || ss==1) ? 9 : 0
|
459
|
+
es = (ss==8 || ss==1) ? 9 : 0
|
460
|
+
if m==0
|
461
|
+
# +-zero
|
462
|
+
e = :zero
|
463
|
+
elsif @infinite_encoded_exp && e==@infinite_encoded_exp && m==0
|
464
|
+
# +-inifinity
|
465
|
+
e = :infinity
|
466
|
+
elsif @nan_encoded_exp && e==@nan_encoded_exp && m!=0
|
467
|
+
# NaN
|
468
|
+
e = :nan
|
469
|
+
else
|
470
|
+
# normalized number
|
471
|
+
# reverse exponent nibbles
|
472
|
+
e = ("%0#{exponent_digits}d"%e).reverse.to_i
|
473
|
+
e = -e if es%2!=0
|
474
|
+
e -= (significand_digits-1)
|
475
|
+
end
|
476
|
+
s = sign_to_unit(s)
|
477
|
+
[s,m,e]
|
478
|
+
end
|
479
|
+
|
480
|
+
def wang2200.pack(s,m,e)
|
481
|
+
s = sign_from_unit(s)
|
482
|
+
msb = radix_power(@significand_digits-1)
|
483
|
+
es = 0
|
484
|
+
if e==:zero
|
485
|
+
e = @zero_encoded_exp
|
486
|
+
m = 0
|
487
|
+
elsif e==:infinity
|
488
|
+
e = @infinite_encoded_exp || radix_power(@fields[:exponent])-1
|
489
|
+
m = 0
|
490
|
+
elsif e==:nan
|
491
|
+
e = @infinite_encoded_exp || radix_power(@fields[:exponent])-1
|
492
|
+
s = minus_sign_value # ?
|
493
|
+
m = radix_power(@significand_digits-2) if m==0
|
494
|
+
elsif e==:denormal
|
495
|
+
e = @denormal_encoded_exp
|
496
|
+
else
|
497
|
+
# to do: try to adjust m to keep e in range if out of valid range
|
498
|
+
# to do: reduce m and adjust e if m too big
|
499
|
+
|
500
|
+
min_exp = radix_min_exp(:integral_significand)
|
501
|
+
if m>0
|
502
|
+
while m<msb && e>min_exp
|
503
|
+
e -= 1
|
504
|
+
m *= radix
|
505
|
+
end
|
506
|
+
end
|
507
|
+
if m<msb && @denormal_encoded_exp
|
508
|
+
e = @denormal_encoded_exp
|
509
|
+
elsif m==0 # => && @denormal_encoded_exp.nil?
|
510
|
+
e = 0
|
511
|
+
else
|
512
|
+
e += (significand_digits-1)
|
513
|
+
if e<0
|
514
|
+
e = -e
|
515
|
+
es = 9
|
516
|
+
else
|
517
|
+
es = 0
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
ss = (s%2) + (es==0 ? 0 : 8)
|
522
|
+
# reverse exponent nibbles
|
523
|
+
e = ("%0#{exponent_digits}d"%e).reverse.to_i
|
524
|
+
pack_fields_hash :signs=>ss, :significand=>m, :exponent=>e
|
525
|
+
end
|
526
|
+
}
|
527
|
+
|
528
|
+
|
529
|
+
# C51 (C compiler for the Intel 8051) BCD Floating point formats
|
530
|
+
class C51BCDFormat < BCDFormat # :nodoc:
|
531
|
+
def self.exponent_radix
|
532
|
+
2
|
533
|
+
end
|
534
|
+
def self.exponent_digits
|
535
|
+
@fields[:exponent_sign]*4-1
|
536
|
+
end
|
537
|
+
def self.minus_sign_value
|
538
|
+
1
|
539
|
+
end
|
540
|
+
def self.unpack(v)
|
541
|
+
f = to_fields_hash(v)
|
542
|
+
m = f[:significand]
|
543
|
+
e_s = f[:exponent_sign]
|
544
|
+
exp_bits = exponent_digits
|
545
|
+
e = e_s & (2**exp_bits-1)
|
546
|
+
s = e_s >> exp_bits
|
547
|
+
if m==0
|
548
|
+
# +-zero
|
549
|
+
e = :zero
|
550
|
+
elsif @infinite_encoded_exp && e==@infinite_encoded_exp && m==0
|
551
|
+
# +-inifinity
|
552
|
+
e = :infinity
|
553
|
+
elsif @nan_encoded_exp && e==@nan_encoded_exp && m!=0
|
554
|
+
# NaN
|
555
|
+
e = :nan
|
556
|
+
else
|
557
|
+
# normalized number
|
558
|
+
e = decode_exponent(e, :integral_significand)
|
559
|
+
end
|
560
|
+
s = sign_to_unit(s)
|
561
|
+
[s,m,e]
|
562
|
+
end
|
563
|
+
def self.bcd_field?(i)
|
564
|
+
@field_meaning[i]==:significand
|
565
|
+
end
|
566
|
+
|
567
|
+
def self.pack(s,m,e)
|
568
|
+
s = sign_from_unit(s)
|
569
|
+
msb = radix_power(@significand_digits-1)
|
570
|
+
es = 0
|
571
|
+
if e==:zero
|
572
|
+
e = @zero_encoded_exp
|
573
|
+
m = 0
|
574
|
+
elsif e==:infinity
|
575
|
+
e = @infinite_encoded_exp || radix_power(@fields[:exponent])-1
|
576
|
+
m = 0
|
577
|
+
elsif e==:nan
|
578
|
+
e = @infinite_encoded_exp || radix_power(@fields[:exponent])-1
|
579
|
+
s = minus_sign_value # ?
|
580
|
+
m = radix_power(@significand_digits-2) if m==0
|
581
|
+
elsif e==:denormal
|
582
|
+
e = @denormal_encoded_exp
|
583
|
+
else
|
584
|
+
# to do: try to adjust m to keep e in range if out of valid range
|
585
|
+
# to do: reduce m and adjust e if m too big
|
586
|
+
|
587
|
+
min_exp = radix_min_exp(:integral_significand)
|
588
|
+
if m>0
|
589
|
+
while m<msb && e>min_exp
|
590
|
+
e -= 1
|
591
|
+
m *= radix
|
592
|
+
end
|
593
|
+
end
|
594
|
+
if m<msb && @denormal_encoded_exp
|
595
|
+
e = @denormal_encoded_exp
|
596
|
+
elsif m==0 # => && @denormal_encoded_exp.nil?
|
597
|
+
e = 0
|
598
|
+
else
|
599
|
+
e = encode_exponent(e, :integral_significand)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
exp_bits = exponent_digits
|
603
|
+
e_s = e + (s << exp_bits)
|
604
|
+
pack_fields_hash :significand=>m, :exponent_sign=>e_s
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
Flt.define :C51_BCD_FLOAT, C51BCDFormat,
|
609
|
+
:fields=>[:exponent_sign, 2, :significand,6],
|
610
|
+
:endiannes=>:big_endian,
|
611
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
612
|
+
:zero_encoded_exp=>0, :min_encoded_exp=>0,:max_encoded_exp=>127
|
613
|
+
|
614
|
+
Flt.define :C51_BCD_DOUBLE,C51BCDFormat,
|
615
|
+
:fields=>[:exponent_sign, 2, :significand,10],
|
616
|
+
:endiannes=>:big_endian,
|
617
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
618
|
+
:zero_encoded_exp=>0, :min_encoded_exp=>0,:max_encoded_exp=>127
|
619
|
+
|
620
|
+
Flt.define :C51_BCD_LONG_DOUBLE, C51BCDFormat,
|
621
|
+
:fields=>[:exponent_sign, 2, :significand,12],
|
622
|
+
:endiannes=>:big_endian,
|
623
|
+
:bias=>64, :bias_mode=>:fractional_significand,
|
624
|
+
:zero_encoded_exp=>0, :min_encoded_exp=>0,:max_encoded_exp=>127
|
625
|
+
|
626
|
+
|
627
|
+
# double-double format as used in the PowerPC
|
628
|
+
Flt.define :IEEE_DOUBLE_DOUBLE, DoubleFormat, :half=>IEEE_binary64, :extra_prec=>true
|
629
|
+
|
630
|
+
|
631
|
+
|
632
|
+
end
|
633
|
+
|