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
data/lib/float-formats/native.rb
CHANGED
@@ -1,273 +1,145 @@
|
|
1
|
-
#Float-Formats -- Native Ruby Float support tools
|
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
|
-
if
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
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
|
-
end
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
# binary representation
|
147
|
-
def float_bin(x)
|
148
|
-
x.nio_write(Nio::Fmt.mode(:sci,:exact).base(2))
|
149
|
-
end
|
150
|
-
|
151
|
-
# decompose a float into a signed integer significand and exponent (base Float::RADIX)
|
152
|
-
def float_to_integral_significand_exponent(x)
|
153
|
-
s,e = Math.frexp(x)
|
154
|
-
[Math.ldexp(s,Float::MANT_DIG).to_i,e-Float::MANT_DIG]
|
155
|
-
end
|
156
|
-
|
157
|
-
# compose float from significand and exponent
|
158
|
-
def float_from_integral_significand_exponent(s,e)
|
159
|
-
Math.ldexp(s,e)
|
160
|
-
end
|
161
|
-
|
162
|
-
def float_to_integral_sign_significand_exponent(x)
|
163
|
-
if x==0.0
|
164
|
-
sign = (1/x<0) ? -1 : +1
|
165
|
-
else
|
166
|
-
sign = x<0 ? -1 : +1
|
167
|
-
end
|
168
|
-
x = -x if sign<0
|
169
|
-
s,e = Math.frexp(x)
|
170
|
-
[sign,Math.ldexp(s,Float::MANT_DIG).to_i,e-Float::MANT_DIG]
|
171
|
-
end
|
172
|
-
|
173
|
-
def float_from_integral_sign_significand_exponent(sgn,s,e)
|
174
|
-
f = Math.ldexp(s,e)
|
175
|
-
f = -f if sgn<0
|
176
|
-
f
|
177
|
-
end
|
178
|
-
|
179
|
-
# convert a float to C99's hexadecimal notation
|
180
|
-
def hex_from_float(v)
|
181
|
-
if Float::RADIX==2
|
182
|
-
sgn,s,e = float_to_integral_sign_significand_exponent(v)
|
183
|
-
else
|
184
|
-
txt = v.nio_write(Fmt.base(2).sep('.')).upcase
|
185
|
-
p = txt.index('E')
|
186
|
-
exp = 0
|
187
|
-
if p
|
188
|
-
exp = rep[p+1..-1].to_i
|
189
|
-
txt = rep[0...p]
|
190
|
-
end
|
191
|
-
p = txt.index('.')
|
192
|
-
if p
|
193
|
-
exp -= (txt.size-p-1)
|
194
|
-
txt.tr!('.','')
|
195
|
-
end
|
196
|
-
s = txt.to_i(2)
|
197
|
-
e = exp
|
198
|
-
end
|
199
|
-
"0x#{sgn<0 ? '-' : ''}#{s.to_s(16)}p#{e}"
|
200
|
-
end
|
201
|
-
|
202
|
-
# convert a string formatted in C99's hexadecimal notation to a float
|
203
|
-
def hex_to_float(txt)
|
204
|
-
txt = txt.strip.upcase
|
205
|
-
txt = txt[2..-1] if txt[0,2]=='0X'
|
206
|
-
p = txt.index('P')
|
207
|
-
if p
|
208
|
-
exp = txt[p+1..-1].to_i
|
209
|
-
txt = txt[0...p]
|
210
|
-
else
|
211
|
-
exp = 0
|
212
|
-
end
|
213
|
-
p = txt.index('.')
|
214
|
-
if p
|
215
|
-
exp -= (txt.size-p-1)*4
|
216
|
-
txt.tr!('.','')
|
217
|
-
end
|
218
|
-
if Float::RADIX==2
|
219
|
-
v = txt.to_i(16)
|
220
|
-
if v==0 && txt.include?('-')
|
221
|
-
sign = -1
|
222
|
-
elsif v<0
|
223
|
-
sign = -1
|
224
|
-
v = -v
|
225
|
-
else
|
226
|
-
sign = +1
|
227
|
-
end
|
228
|
-
float_from_integral_sign_significand_exponent(sign,v,exp)
|
229
|
-
else
|
230
|
-
(txt.to_i(16)*(2**exp)).to_f
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
# ===== IEEE types =====================================================================================
|
235
|
-
|
236
|
-
# generate a SGL value stored in a byte string given a decimal value formatted as text
|
237
|
-
def sgl_from_text(txt, little_endian=true)
|
238
|
-
code = little_endian ? 'e':'g'
|
239
|
-
[txt].pack(code)
|
240
|
-
end
|
241
|
-
|
242
|
-
# generate a SGL value stored in a byte string given a Float value
|
243
|
-
def sgl_from_float(val, little_endian=true)
|
244
|
-
code = little_endian ? 'e':'g'
|
245
|
-
[val].pack(code)
|
246
|
-
end
|
247
|
-
|
248
|
-
# convert a SGL value stored in a byte string to a Float value
|
249
|
-
def sgl_to_float(sgl, littel_endian=true)
|
250
|
-
code = little_endian ? 'e':'g'
|
251
|
-
sgl.unpack(code)[0]
|
252
|
-
end
|
253
|
-
|
254
|
-
|
255
|
-
# generate a DBL value stored in a byte string given a decimal value formatted as text
|
256
|
-
def dbl_from_text(txt, little_endian=true)
|
257
|
-
code = little_endian ? 'E':'G'
|
258
|
-
[txt].pack(code)
|
259
|
-
end
|
260
|
-
|
261
|
-
# generate a DBL value stored in a byte string given a Float value
|
262
|
-
def dbl_from_float(val, little_endian=true)
|
263
|
-
code = little_endian ? 'E':'G'
|
264
|
-
[val].pack(code)
|
265
|
-
end
|
266
|
-
|
267
|
-
# convert a DBL value stored in a byte string to a Float value
|
268
|
-
def dbl_to_float(sgl, little_endian=true)
|
269
|
-
code = little_endian ? 'E':'G'
|
270
|
-
sgl.unpack(code)[0]
|
271
|
-
end
|
272
|
-
|
1
|
+
#Float-Formats -- Native Ruby Float support tools
|
2
|
+
|
3
|
+
require 'nio'
|
4
|
+
require 'nio/sugar'
|
5
|
+
require 'flt'
|
6
|
+
require 'flt/float'
|
7
|
+
require 'float-formats/bytes'
|
8
|
+
|
9
|
+
module Flt
|
10
|
+
|
11
|
+
module_function
|
12
|
+
|
13
|
+
# shortest decimal unambiguous reprentation
|
14
|
+
def float_shortest_dec(x)
|
15
|
+
x.nio_write(Nio::Fmt.prec(:exact))
|
16
|
+
end
|
17
|
+
|
18
|
+
# decimal representation showing all significant digits
|
19
|
+
def float_significant_dec(x)
|
20
|
+
x.nio_write(Nio::Fmt.prec(:exact).show_all_digits(true))
|
21
|
+
end
|
22
|
+
|
23
|
+
# complete exact decimal representation
|
24
|
+
def float_dec(x)
|
25
|
+
x.nio_write(Nio::Fmt.prec(:exact).approx_mode(:exact))
|
26
|
+
end
|
27
|
+
|
28
|
+
# binary representation
|
29
|
+
def float_bin(x)
|
30
|
+
x.nio_write(Nio::Fmt.mode(:sci,:exact).base(2))
|
31
|
+
end
|
32
|
+
|
33
|
+
# decompose a float into a signed integer significand and exponent (base Float::RADIX)
|
34
|
+
def float_to_integral_significand_exponent(x)
|
35
|
+
Float.context.to_int_scale(x)
|
36
|
+
end
|
37
|
+
|
38
|
+
# compose float from significand and exponent
|
39
|
+
def float_from_integral_significand_exponent(s,e)
|
40
|
+
Float.context.Num(s,e)
|
41
|
+
end
|
42
|
+
|
43
|
+
def float_to_integral_sign_significand_exponent(x)
|
44
|
+
Float.context.split(x)
|
45
|
+
end
|
46
|
+
|
47
|
+
def float_from_integral_sign_significand_exponent(sgn,s,e)
|
48
|
+
Float.context.Num(sgn,s,e)
|
49
|
+
end
|
50
|
+
|
51
|
+
# convert a float to C99's hexadecimal notation
|
52
|
+
def hex_from_float(v)
|
53
|
+
if Float::RADIX==2
|
54
|
+
sgn,s,e = float_to_integral_sign_significand_exponent(v)
|
55
|
+
else
|
56
|
+
txt = v.nio_write(Fmt.base(2).sep('.')).upcase
|
57
|
+
p = txt.index('E')
|
58
|
+
exp = 0
|
59
|
+
if p
|
60
|
+
exp = rep[p+1..-1].to_i
|
61
|
+
txt = rep[0...p]
|
62
|
+
end
|
63
|
+
p = txt.index('.')
|
64
|
+
if p
|
65
|
+
exp -= (txt.size-p-1)
|
66
|
+
txt.tr!('.','')
|
67
|
+
end
|
68
|
+
s = txt.to_i(2)
|
69
|
+
e = exp
|
70
|
+
end
|
71
|
+
"0x#{sgn<0 ? '-' : ''}#{s.to_s(16)}p#{e}"
|
72
|
+
end
|
73
|
+
|
74
|
+
# convert a string formatted in C99's hexadecimal notation to a float
|
75
|
+
def hex_to_float(txt)
|
76
|
+
txt = txt.strip.upcase
|
77
|
+
txt = txt[2..-1] if txt[0,2]=='0X'
|
78
|
+
p = txt.index('P')
|
79
|
+
if p
|
80
|
+
exp = txt[p+1..-1].to_i
|
81
|
+
txt = txt[0...p]
|
82
|
+
else
|
83
|
+
exp = 0
|
84
|
+
end
|
85
|
+
p = txt.index('.')
|
86
|
+
if p
|
87
|
+
exp -= (txt.size-p-1)*4
|
88
|
+
txt.tr!('.','')
|
89
|
+
end
|
90
|
+
if Float::RADIX==2
|
91
|
+
v = txt.to_i(16)
|
92
|
+
if v==0 && txt.include?('-')
|
93
|
+
sign = -1
|
94
|
+
elsif v<0
|
95
|
+
sign = -1
|
96
|
+
v = -v
|
97
|
+
else
|
98
|
+
sign = +1
|
99
|
+
end
|
100
|
+
float_from_integral_sign_significand_exponent(sign,v,exp)
|
101
|
+
else
|
102
|
+
(txt.to_i(16)*(2**exp)).to_f
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# ===== IEEE types =====================================================================================
|
107
|
+
|
108
|
+
# generate a SGL value stored in a byte string given a decimal value formatted as text
|
109
|
+
def sgl_from_text(txt, little_endian=true)
|
110
|
+
code = little_endian ? 'e':'g'
|
111
|
+
[txt].pack(code)
|
112
|
+
end
|
113
|
+
|
114
|
+
# generate a SGL value stored in a byte string given a Float value
|
115
|
+
def sgl_from_float(val, little_endian=true)
|
116
|
+
code = little_endian ? 'e':'g'
|
117
|
+
[val].pack(code)
|
118
|
+
end
|
119
|
+
|
120
|
+
# convert a SGL value stored in a byte string to a Float value
|
121
|
+
def sgl_to_float(sgl, littel_endian=true)
|
122
|
+
code = little_endian ? 'e':'g'
|
123
|
+
sgl.unpack(code)[0]
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
# generate a DBL value stored in a byte string given a decimal value formatted as text
|
128
|
+
def dbl_from_text(txt, little_endian=true)
|
129
|
+
code = little_endian ? 'E':'G'
|
130
|
+
[txt].pack(code)
|
131
|
+
end
|
132
|
+
|
133
|
+
# generate a DBL value stored in a byte string given a Float value
|
134
|
+
def dbl_from_float(val, little_endian=true)
|
135
|
+
code = little_endian ? 'E':'G'
|
136
|
+
[val].pack(code)
|
137
|
+
end
|
138
|
+
|
139
|
+
# convert a DBL value stored in a byte string to a Float value
|
140
|
+
def dbl_to_float(sgl, little_endian=true)
|
141
|
+
code = little_endian ? 'E':'G'
|
142
|
+
sgl.unpack(code)[0]
|
143
|
+
end
|
144
|
+
|
273
145
|
end
|
data/tasks/ann.rake
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
begin
|
3
|
+
require 'bones/smtp_tls'
|
4
|
+
rescue LoadError
|
5
|
+
require 'net/smtp'
|
6
|
+
end
|
7
|
+
require 'time'
|
8
|
+
|
9
|
+
namespace :ann do
|
10
|
+
|
11
|
+
# A prerequisites task that all other tasks depend upon
|
12
|
+
task :prereqs
|
13
|
+
|
14
|
+
file PROJ.ann.file do
|
15
|
+
ann = PROJ.ann
|
16
|
+
puts "Generating #{ann.file}"
|
17
|
+
File.open(ann.file,'w') do |fd|
|
18
|
+
fd.puts("#{PROJ.name} version #{PROJ.version}")
|
19
|
+
fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
|
20
|
+
fd.puts(" #{PROJ.url}") if PROJ.url.valid?
|
21
|
+
fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
|
22
|
+
fd.puts
|
23
|
+
fd.puts("== DESCRIPTION")
|
24
|
+
fd.puts
|
25
|
+
fd.puts(PROJ.description)
|
26
|
+
fd.puts
|
27
|
+
fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
|
28
|
+
fd.puts
|
29
|
+
ann.paragraphs.each do |p|
|
30
|
+
fd.puts "== #{p.upcase}"
|
31
|
+
fd.puts
|
32
|
+
fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
|
33
|
+
fd.puts
|
34
|
+
end
|
35
|
+
fd.puts ann.text if ann.text
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Create an announcement file"
|
40
|
+
task :announcement => ['ann:prereqs', PROJ.ann.file]
|
41
|
+
|
42
|
+
desc "Send an email announcement"
|
43
|
+
task :email => ['ann:prereqs', PROJ.ann.file] do
|
44
|
+
ann = PROJ.ann
|
45
|
+
from = ann.email[:from] || Array(PROJ.authors).first || PROJ.email
|
46
|
+
to = Array(ann.email[:to])
|
47
|
+
|
48
|
+
### build a mail header for RFC 822
|
49
|
+
rfc822msg = "From: #{from}\n"
|
50
|
+
rfc822msg << "To: #{to.join(',')}\n"
|
51
|
+
rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
|
52
|
+
rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
|
53
|
+
rfc822msg << "\n"
|
54
|
+
rfc822msg << "Date: #{Time.new.rfc822}\n"
|
55
|
+
rfc822msg << "Message-Id: "
|
56
|
+
rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
|
57
|
+
rfc822msg << File.read(ann.file)
|
58
|
+
|
59
|
+
params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
|
60
|
+
ann.email[key]
|
61
|
+
end
|
62
|
+
|
63
|
+
params[3] = PROJ.email if params[3].nil?
|
64
|
+
|
65
|
+
if params[4].nil?
|
66
|
+
STDOUT.write "Please enter your e-mail password (#{params[3]}): "
|
67
|
+
params[4] = STDIN.gets.chomp
|
68
|
+
end
|
69
|
+
|
70
|
+
### send email
|
71
|
+
Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
|
72
|
+
end
|
73
|
+
end # namespace :ann
|
74
|
+
|
75
|
+
desc 'Alias to ann:announcement'
|
76
|
+
task :ann => 'ann:announcement'
|
77
|
+
|
78
|
+
CLOBBER << PROJ.ann.file
|
79
|
+
|
80
|
+
# EOF
|