flt 1.3.0 → 1.3.1
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.
- checksums.yaml +7 -0
- data/.gitignore +28 -0
- data/Gemfile +3 -0
- data/History.txt +4 -0
- data/Manifest.txt +1 -2
- data/{README.txt → README.rdoc} +24 -15
- data/Rakefile +15 -30
- data/expand.rb +177 -0
- data/flt.gemspec +23 -0
- data/lib/flt.rb +1 -1
- data/lib/flt/float.rb +1 -1
- data/lib/flt/num.rb +88 -27
- data/lib/flt/sugar.rb +3 -0
- data/lib/flt/tolerance.rb +1 -1
- data/lib/flt/version.rb +1 -7
- data/test/test_define_conversions.rb +4 -4
- data/test/test_sugar.rb +5 -5
- metadata +64 -87
- data/tasks/ann.rake +0 -80
- data/tasks/bones.rake +0 -20
- data/tasks/gem.rake +0 -192
- data/tasks/git.rake +0 -40
- data/tasks/manifest.rake +0 -48
- data/tasks/notes.rake +0 -27
- data/tasks/post_load.rake +0 -39
- data/tasks/rdoc.rake +0 -50
- data/tasks/rubyforge.rake +0 -55
- data/tasks/setup.rb +0 -279
- data/tasks/spec.rake +0 -54
- data/tasks/svn.rake +0 -47
- data/tasks/test.rake +0 -40
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4361f2aa54884af4cc140d8caa5e7575b57faded
|
4
|
+
data.tar.gz: 98b581886ff91b9ba8be1ca2cf0030f4d0a6878b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d600399045683b9ac8b7db526f3c7f4065bc98f869076b829ea165dece35a6c630b723d694c2bf642af148ca19efe624af68a3749f24a011ca501462aa3ac111
|
7
|
+
data.tar.gz: ca163347091dbb34ec079438b54583b759cf6e334a0d4305f668d1de4838e13fceb53726bad9b41fdedb435f0856686df9a62815fccf23af2c9170d7f804d011
|
data/.gitignore
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
test/dectest/*
|
2
|
+
email.txt
|
3
|
+
ruby-decimal.gemspec
|
4
|
+
html
|
5
|
+
.DS_Store
|
6
|
+
pkg
|
7
|
+
.rbx
|
8
|
+
rdoc
|
9
|
+
test/trigtest
|
10
|
+
test/tmp
|
11
|
+
*.gem
|
12
|
+
*.rbc
|
13
|
+
.bundle
|
14
|
+
.config
|
15
|
+
.yardoc
|
16
|
+
Gemfile.lock
|
17
|
+
InstalledFiles
|
18
|
+
_yardoc
|
19
|
+
coverage
|
20
|
+
doc/
|
21
|
+
lib/bundler/man
|
22
|
+
flt/version_tmp
|
23
|
+
tmp
|
24
|
+
*.bundle
|
25
|
+
*.so
|
26
|
+
*.o
|
27
|
+
*.a
|
28
|
+
mkmf.log
|
data/Gemfile
ADDED
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/{README.txt → README.rdoc}
RENAMED
@@ -1,4 +1,5 @@
|
|
1
1
|
= Introduction
|
2
|
+
{<img src="https://badge.fury.io/rb/flt.svg" alt="Gem Version" />}[http://badge.fury.io/rb/flt]
|
2
3
|
|
3
4
|
This library provides arbitrary precision floating-point types for Ruby. All types and
|
4
5
|
functions are within a namespace called Flt. Decimal and Binary floating point numbers
|
@@ -20,7 +21,7 @@ This library is the successor of the ruby-decimal gem, that defined the Decimal
|
|
20
21
|
for decimal floating point; that class has been renamed to Flt::DecNum and support
|
21
22
|
has been added for binary floating point and tolerances.
|
22
23
|
|
23
|
-
The documentation for this package is available at http://
|
24
|
+
The documentation for this package is available at http://rdoc.info/github/jgoizueta/flt/frames
|
24
25
|
|
25
26
|
The code is at http://github.com/jgoizueta/flt/
|
26
27
|
|
@@ -31,14 +32,14 @@ It is based on the Python Decimal class.
|
|
31
32
|
|
32
33
|
== Standars compliance.
|
33
34
|
|
34
|
-
DecNum
|
35
|
+
DecNum is designed to be conformant to the General Decimal Arithmetic Specification
|
35
36
|
and the revised IEEE 754 standard (IEEE 754-2008).
|
36
37
|
|
37
38
|
= Examples of use
|
38
39
|
|
39
|
-
To install the library use gem from the command line:
|
40
|
-
|
41
|
-
|
40
|
+
To install the library use gem from the command line:
|
41
|
+
|
42
|
+
gem install flt
|
42
43
|
|
43
44
|
Then require the library in your code (if it fails you may need to <tt>require 'rubygems'</tt> first)
|
44
45
|
require 'flt'
|
@@ -60,7 +61,7 @@ Each thread has an active context that can be accessed like this:
|
|
60
61
|
|
61
62
|
puts DecNum.context.precision # -> 28
|
62
63
|
|
63
|
-
The active context can be globally for the current thread:
|
64
|
+
The active context can be modified globally for the current thread:
|
64
65
|
|
65
66
|
DecNum.context.precision = 2
|
66
67
|
puts DecNum.context.precision # -> 2
|
@@ -85,7 +86,7 @@ The block for a local context can be passed the current context as an argument:
|
|
85
86
|
end
|
86
87
|
puts DecNum.context.precision # -> 9
|
87
88
|
|
88
|
-
A context object can be used to define the local context:
|
89
|
+
A context object can also be used to define the local context:
|
89
90
|
|
90
91
|
my_context = DecNum::Context(:precision=>20)
|
91
92
|
DecNum.context(my_context) do |context|
|
@@ -101,7 +102,6 @@ And individual parameters can be assigned like this:
|
|
101
102
|
puts context.rounding # -> down
|
102
103
|
end
|
103
104
|
|
104
|
-
|
105
105
|
Contexts created with the DecNum::Context() constructor
|
106
106
|
inherit from DecNum::DefaultContext.
|
107
107
|
Default context attributes can be established by modifying
|
@@ -168,7 +168,7 @@ the plus operator to force rounding here:
|
|
168
168
|
puts x # -> 123.45678
|
169
169
|
puts +x # -> 123.5
|
170
170
|
|
171
|
-
Precision can be also set to exact to avoid rounding, by using
|
171
|
+
Precision can be also set to 'exact' to avoid rounding, by using
|
172
172
|
the exact property or using a 0 precision. In exact mode results
|
173
173
|
are never rounded and results that have an infinite number of
|
174
174
|
digits trigger the DecNum::Inexact exception.
|
@@ -186,7 +186,7 @@ digits trigger the DecNum::Inexact exception.
|
|
186
186
|
puts DecNum(1)/DecNum(3) # -> 0.33333
|
187
187
|
|
188
188
|
There are also some methods for explicit rounding that provide
|
189
|
-
an interface compatible with the Ruby
|
189
|
+
an interface compatible with that of the Ruby Float class:
|
190
190
|
|
191
191
|
puts DecNum('101.5').round # -> 102
|
192
192
|
puts DecNum('101.5').round(0) # -> 102
|
@@ -204,8 +204,8 @@ an interface compatible with the Ruby interface of Float:
|
|
204
204
|
In addition to finite numbers, a DecNum object can represent some special values:
|
205
205
|
* Infinity (+Infinity, -Infinity). The method DecNum#infinite? returns true for these to values.
|
206
206
|
DecNum.infinity DecNum.infinity(-1) can be used to get these values.
|
207
|
-
* NaN (not a number) represents
|
208
|
-
DecNum.nan can be used to obtain it. There is a variant, sNaN (signaling NaN) that
|
207
|
+
* NaN (not a number) represents undefined results. The method DecNum#nan? returns true for it and
|
208
|
+
DecNum.nan can be used to obtain it. There is a variant, sNaN (signaling NaN) that causes
|
209
209
|
an invalid operation condition if used; it can be detected with DecNum.snan?.
|
210
210
|
A NaN can also include diagnostic information in its sign and coefficient.
|
211
211
|
|
@@ -213,8 +213,8 @@ Any of the special values can be detected with DecNum#special?
|
|
213
213
|
Finite numbers can be clasified with
|
214
214
|
these methods:
|
215
215
|
* DecNum#zero? detects a zero value (note that there are two zero values: +0 and -0)
|
216
|
-
* DecNum#normal? detects normal values: those whose adjusted exponents are not less than
|
217
|
-
* DecNum#subnormal? detects subnormal values: those whose adjusted exponents are less than
|
216
|
+
* DecNum#normal? detects normal values: those whose adjusted exponents are not less than @emin@.
|
217
|
+
* DecNum#subnormal? detects subnormal values: those whose adjusted exponents are less than @emin@.
|
218
218
|
|
219
219
|
==Exceptions
|
220
220
|
|
@@ -557,21 +557,30 @@ the code cleaner and the results more easily predictable.
|
|
557
557
|
|
558
558
|
DecNum.context.precision = 10
|
559
559
|
puts DecNum(1)/DecNum(3)
|
560
|
+
|
560
561
|
Contexts are thread-safe and can be used for individual operations:
|
562
|
+
|
561
563
|
puts DecNum(1).divide(DecNum(e), DecNum::Context(:precision=>4))
|
564
|
+
|
562
565
|
Which can be abbreviated:
|
563
|
-
|
566
|
+
|
567
|
+
puts DecNum(1).divide(DecNum(e), :precision=>4)
|
568
|
+
|
564
569
|
Or use locally in a block without affecting other code:
|
570
|
+
|
565
571
|
DecNum.context {
|
566
572
|
DecNum.context.precision = 3
|
567
573
|
puts DecNum(1)/DecNum(3)
|
568
574
|
}
|
569
575
|
puts DecNum.context.precision
|
576
|
+
|
570
577
|
Which can also be abbreviated:
|
578
|
+
|
571
579
|
DecNum.context(:precision=>3) { puts DecNum(1)/DecNum(3) }
|
572
580
|
|
573
581
|
This allows in general to write simpler code; e.g. this is an exponential function, adapted from the
|
574
582
|
'recipes' in Python's Decimal:
|
583
|
+
|
575
584
|
def exp(x, c=nil)
|
576
585
|
i, lasts, s, fact, num = 0, 0, 1, 1, 1
|
577
586
|
DecNum.context(c) do |context|
|
data/Rakefile
CHANGED
@@ -1,34 +1,19 @@
|
|
1
|
-
|
2
|
-
# configured in this Rakefile. The .rake files in the tasks directory
|
3
|
-
# are where the options are used.
|
1
|
+
require "bundler/gem_tasks"
|
4
2
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
require 'rake/testtask'
|
4
|
+
Rake::TestTask.new(:test) do |test|
|
5
|
+
test.libs << 'lib' << 'test'
|
6
|
+
test.pattern = 'test/**/test_*.rb'
|
7
|
+
test.verbose = true
|
10
8
|
end
|
11
9
|
|
12
|
-
|
13
|
-
|
10
|
+
require 'rdoc/task'
|
11
|
+
Rake::RDocTask.new do |rdoc|
|
12
|
+
version = File.exist?('VERSION') ? File.read('VERSION').strip : Flt::VERSION
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
PROJ.email = 'javier@goizueta.info'
|
22
|
-
PROJ.version = Flt::VERSION::STRING
|
23
|
-
PROJ.rubyforge.name = 'flt'
|
24
|
-
PROJ.url = "http://#{PROJ.rubyforge.name}.rubyforge.org"
|
25
|
-
PROJ.rdoc.opts = [
|
26
|
-
"--main", "README.txt",
|
27
|
-
'--title', 'Ruby Flt Documentation',
|
28
|
-
"--opname", "index.html",
|
29
|
-
"--line-numbers",
|
30
|
-
"--inline-source"
|
31
|
-
]
|
32
|
-
#PROJ.test.file = 'test/all_tests.rb'
|
33
|
-
|
34
|
-
# EOF
|
14
|
+
rdoc.rdoc_dir = 'rdoc'
|
15
|
+
rdoc.title = "Flt #{version}"
|
16
|
+
rdoc.main = "README.rdoc"
|
17
|
+
rdoc.rdoc_files.include('README*')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
data/expand.rb
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
require 'irb/ruby-lex'
|
2
|
+
require 'stringio'
|
3
|
+
|
4
|
+
class MimickIRB < RubyLex
|
5
|
+
attr_accessor :started
|
6
|
+
|
7
|
+
class Continue < StandardError; end
|
8
|
+
class Empty < StandardError; end
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
super
|
12
|
+
set_input(StringIO.new)
|
13
|
+
end
|
14
|
+
|
15
|
+
def run(str,line_no=nil)
|
16
|
+
obj = nil
|
17
|
+
@io << str
|
18
|
+
@io.rewind
|
19
|
+
unless l = lex
|
20
|
+
raise Empty if @line == ''
|
21
|
+
else
|
22
|
+
case l.strip
|
23
|
+
when "reset"
|
24
|
+
@line = ""
|
25
|
+
when "time"
|
26
|
+
@line = "puts %{You started \#{IRBalike.started.since} ago.}"
|
27
|
+
else
|
28
|
+
@line << l << "\n"
|
29
|
+
if @ltype or @continue or @indent > 0
|
30
|
+
raise Continue
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
unless @line.empty?
|
35
|
+
obj = eval @line, TOPLEVEL_BINDING
|
36
|
+
end
|
37
|
+
@line = ''
|
38
|
+
#@line_no = line_no if line_no
|
39
|
+
@exp_line_no = line_no || @line_no
|
40
|
+
|
41
|
+
@indent = 0
|
42
|
+
@indent_stack = []
|
43
|
+
|
44
|
+
$stdout.rewind
|
45
|
+
output = $stdout.read
|
46
|
+
$stdout.truncate(0)
|
47
|
+
$stdout.rewind
|
48
|
+
[output, obj]
|
49
|
+
rescue Object => e
|
50
|
+
case e when Empty, Continue
|
51
|
+
else @line = ""
|
52
|
+
end
|
53
|
+
raise e
|
54
|
+
ensure
|
55
|
+
set_input(StringIO.new)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
# TO DO: output of blocks is gathered and shown at the end of the block
|
61
|
+
# when lines in a block have # -> markers, they should be rememberd, and when
|
62
|
+
# output is generated when closing the block, each output line should
|
63
|
+
# be appended to the in-block # -> lines before showing lines after the block.
|
64
|
+
|
65
|
+
|
66
|
+
class ExampleExpander
|
67
|
+
def initialize(sep="# -> ", align=51)
|
68
|
+
@sep = sep
|
69
|
+
@align = align
|
70
|
+
@irb = MimickIRB.new
|
71
|
+
@output = ""
|
72
|
+
end
|
73
|
+
def add_line(line,line_num=nil)
|
74
|
+
line = line.chomp
|
75
|
+
line = $1 if /(.+)#{@sep}.*/.match line
|
76
|
+
$stdout = StringIO.new
|
77
|
+
begin
|
78
|
+
out,obj = @irb.run(line, line_num)
|
79
|
+
@output << line_output(line,out)
|
80
|
+
rescue MimickIRB::Empty
|
81
|
+
@output << line_output(line)
|
82
|
+
rescue MimickIRB::Continue
|
83
|
+
@output << line_output(line)
|
84
|
+
rescue Object => e
|
85
|
+
#msg = "Exception : #{e.message}"
|
86
|
+
msg = "Exception : #{e.class}"
|
87
|
+
# msg = "#{e.class}: #{e.message}"
|
88
|
+
@output << line_output(line,msg)
|
89
|
+
STDERR.puts "#{msg}\n"
|
90
|
+
end
|
91
|
+
$stdout = STDOUT
|
92
|
+
end
|
93
|
+
def output
|
94
|
+
@output
|
95
|
+
end
|
96
|
+
def clear
|
97
|
+
@output = ""
|
98
|
+
end
|
99
|
+
protected
|
100
|
+
def line_output(line,output=nil)
|
101
|
+
if output
|
102
|
+
output = output.chomp
|
103
|
+
output = nil if output.strip.empty?
|
104
|
+
end
|
105
|
+
out = line.dup
|
106
|
+
if output
|
107
|
+
line_size = line.size
|
108
|
+
output.split("\n").each do |out_line|
|
109
|
+
out << " "*[0,(@align-line_size)].max + @sep + out_line
|
110
|
+
out << "\n"
|
111
|
+
line_size = 0
|
112
|
+
end
|
113
|
+
end
|
114
|
+
out
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
def expand_text(txt,non_code_block_prefix=nil) # text with indented blocks of code
|
120
|
+
exex = ExampleExpander.new
|
121
|
+
indent = nil
|
122
|
+
|
123
|
+
txt_out = ""
|
124
|
+
|
125
|
+
line_num = 0
|
126
|
+
accum = ""
|
127
|
+
skip_until_blank = false
|
128
|
+
disabled = false
|
129
|
+
txt.split("\n").each do |line|
|
130
|
+
line_num += 1
|
131
|
+
code = false
|
132
|
+
line.chomp!
|
133
|
+
|
134
|
+
if skip_until_blank
|
135
|
+
if line.strip.empty?
|
136
|
+
skip_until_blank = false
|
137
|
+
end
|
138
|
+
else
|
139
|
+
|
140
|
+
unless line.strip.empty? || disabled
|
141
|
+
line_indent = /^\s*/.match(line)[0]
|
142
|
+
indent ||= line_indent
|
143
|
+
indent = line_indent if line_indent.size < indent.size
|
144
|
+
if line[line_indent.size,1]=='*'
|
145
|
+
inner_indent = /^\s*/.match(line[line_indent.size+1..-1])[0]
|
146
|
+
indent += '*'+inner_indent
|
147
|
+
else
|
148
|
+
if line_indent.size > indent.size
|
149
|
+
code = true
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
if code
|
154
|
+
exex.add_line line, line_num
|
155
|
+
line = exex.output.chomp
|
156
|
+
exex.clear
|
157
|
+
else
|
158
|
+
disabled = true if line[0,7]=="EXPAND-"
|
159
|
+
disabled = false if line[0,7]=="EXPAND+"
|
160
|
+
skip_until_blank = true if line[0,1]==non_code_block_prefix
|
161
|
+
end
|
162
|
+
end
|
163
|
+
txt_out << line + "\n"
|
164
|
+
end
|
165
|
+
txt_out
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
require 'rubygems'
|
170
|
+
|
171
|
+
$:.unshift File.dirname(__FILE__) + '/lib'
|
172
|
+
|
173
|
+
|
174
|
+
require File.dirname(__FILE__) + '/lib/flt'
|
175
|
+
|
176
|
+
|
177
|
+
puts expand_text(File.read(ARGV.shift),"[")
|
data/flt.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'flt/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "flt"
|
8
|
+
spec.version = Flt::VERSION
|
9
|
+
spec.authors = ["Javier Goizueta"]
|
10
|
+
spec.email = ["jgoizueta@gmail.com"]
|
11
|
+
spec.summary = %q{Floating Point Numbers}
|
12
|
+
spec.description = %q{Decimal and binary arbitrary precision floating point numbers in pure Ruby.}
|
13
|
+
spec.homepage = "http://github.com/jgoizueta/flt"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/lib/flt.rb
CHANGED