ieee-fpu 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +35 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +95 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/ext/extconf.rb +17 -0
- data/ext/ieee_fpu_control.c +121 -0
- data/ieee-fpu.gemspec +65 -0
- data/lib/ieee-fpu.rb +424 -0
- data/test/helper.rb +48 -0
- data/test/test_ieee-fpu.rb +55 -0
- metadata +144 -0
data/.document
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
|
6
|
+
# Add dependencies to develop your gem here.
|
7
|
+
# Include everything needed to run rake, tests, features, etc.
|
8
|
+
group :development do
|
9
|
+
gem "shoulda", ">= 0"
|
10
|
+
gem "rdoc", "~> 3.12"
|
11
|
+
gem "bundler", "~> 1"
|
12
|
+
gem "jeweler", "~> 1.8.4"
|
13
|
+
gem "flt"
|
14
|
+
end
|
15
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.2.8)
|
5
|
+
i18n (~> 0.6)
|
6
|
+
multi_json (~> 1.0)
|
7
|
+
flt (1.3.0)
|
8
|
+
git (1.2.5)
|
9
|
+
i18n (0.6.1)
|
10
|
+
jeweler (1.8.4)
|
11
|
+
bundler (~> 1.0)
|
12
|
+
git (>= 1.2.5)
|
13
|
+
rake
|
14
|
+
rdoc
|
15
|
+
json (1.7.5)
|
16
|
+
multi_json (1.3.6)
|
17
|
+
rake (0.9.2.2)
|
18
|
+
rdoc (3.12)
|
19
|
+
json (~> 1.4)
|
20
|
+
shoulda (3.1.1)
|
21
|
+
shoulda-context (~> 1.0)
|
22
|
+
shoulda-matchers (~> 1.2)
|
23
|
+
shoulda-context (1.0.0)
|
24
|
+
shoulda-matchers (1.3.0)
|
25
|
+
activesupport (>= 3.0.0)
|
26
|
+
|
27
|
+
PLATFORMS
|
28
|
+
ruby
|
29
|
+
|
30
|
+
DEPENDENCIES
|
31
|
+
bundler (~> 1)
|
32
|
+
flt
|
33
|
+
jeweler (~> 1.8.4)
|
34
|
+
rdoc (~> 3.12)
|
35
|
+
shoulda
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Javier Goizueta
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
= ieee-fpu
|
2
|
+
|
3
|
+
Ruby gem for the control of IEEE compliant FPUs rounding mode and precision (if available).
|
4
|
+
|
5
|
+
IEEE_FPU has two writeable properties:
|
6
|
+
|
7
|
+
* rounding which has values :even, :up, :down and :zero
|
8
|
+
* precision with values :single, :double and :extended
|
9
|
+
|
10
|
+
The latter property is not available in all IEEE FPUs
|
11
|
+
|
12
|
+
The scope method can be used to set up an scope in which
|
13
|
+
FPU properties are modified; when the scope is exited
|
14
|
+
the FPU state is restored.
|
15
|
+
|
16
|
+
Examples:
|
17
|
+
|
18
|
+
puts IEEE_FPU.rounding # -> even
|
19
|
+
puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
20
|
+
IEEE_FPU.scope {
|
21
|
+
IEEE_FPU.rounding = :down
|
22
|
+
puts IEEE_FPU.rounding # -> down
|
23
|
+
puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
24
|
+
}
|
25
|
+
IEEE_FPU.scope { |fpu|
|
26
|
+
fpu.rounding = :up
|
27
|
+
puts IEEE_FPU.rounding # -> up
|
28
|
+
puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000022204
|
29
|
+
}
|
30
|
+
puts IEEE_FPU.rounding # -> even
|
31
|
+
puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
32
|
+
|
33
|
+
expr = '(3.2-2.0)-1.2'
|
34
|
+
IEEE_FPU.scope {
|
35
|
+
IEEE_FPU.precision = :single # -> 0.0
|
36
|
+
puts eval(expr)
|
37
|
+
}
|
38
|
+
IEEE_FPU.scope {
|
39
|
+
IEEE_FPU.precision = :double
|
40
|
+
puts eval(expr) # -> 2.22044604925031e-16
|
41
|
+
}
|
42
|
+
|
43
|
+
Note: IEEE_FPU.precision=:extended has a very limited influence in Ruby
|
44
|
+
because all results are casted to Float (double) values.
|
45
|
+
Its effect is more noticeable in C/C++ extensions.
|
46
|
+
|
47
|
+
FPU parameters can be assigneed passign a hash to the scope method:
|
48
|
+
IEEE_FPU.scope(:precision=>:single) {
|
49
|
+
puts eval(expr)
|
50
|
+
}
|
51
|
+
|
52
|
+
An array can be passed for one (only one) of the parameters;
|
53
|
+
the block will be repeated with every value of the parameter
|
54
|
+
and the results will be collected in an array.
|
55
|
+
|
56
|
+
For example this checks the result of an expression in all
|
57
|
+
the rounding modes:
|
58
|
+
|
59
|
+
puts IEEE_FPU.scope(:rounding=>[:even,:up,:down,:zero]) {
|
60
|
+
1.0 + Float::EPSILON/2
|
61
|
+
}.inspect
|
62
|
+
|
63
|
+
Different parameters can be passed to each call of the block
|
64
|
+
by assigning an array to :parameters
|
65
|
+
|
66
|
+
For example, interval arithmetic could be implementes like this:
|
67
|
+
|
68
|
+
def sum_intervals(i1,i2)
|
69
|
+
IEEE_FPU.scope(:rounding=>[:down,:up],:parameters=>[0,1]) do |fpu,i|
|
70
|
+
i1[i]+i2[i]
|
71
|
+
end
|
72
|
+
end
|
73
|
+
i = sum_intervals([1.0]*2, [Float::EPSILON/2]*2)
|
74
|
+
|
75
|
+
== TODO
|
76
|
+
|
77
|
+
* Gem with the C extension; avoid compiling under mswin32 if possible (the extension is not needed)
|
78
|
+
* Binary gems for mingw32
|
79
|
+
* Rename IEEE_FPU, review API design
|
80
|
+
* Flt interoperatibility
|
81
|
+
|
82
|
+
== Contributing to ieee-fpu
|
83
|
+
|
84
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
85
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
86
|
+
* Fork the project.
|
87
|
+
* Start a feature/bugfix branch.
|
88
|
+
* Commit and push until you are happy with your contribution.
|
89
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
90
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
91
|
+
|
92
|
+
== Copyright
|
93
|
+
|
94
|
+
Copyright (c) 2007, 2012 Javier Goizueta. See LICENSE.txt for
|
95
|
+
further details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "ieee-fpu"
|
18
|
+
gem.homepage = "http://github.com/jgoizueta/ieee-fpu"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Control of IEEE compliant FPUs rounding mode and precision}
|
21
|
+
gem.description = %Q{Control of IEEE compliant FPUs rounding mode and precision}
|
22
|
+
gem.email = "jgoizueta@gmail.com"
|
23
|
+
gem.authors = ["Javier Goizueta"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
gem.extensions = ['ext/extconf.rb']
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
task :default => :test
|
37
|
+
|
38
|
+
require 'rdoc/task'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "ieee-fpu #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/ext/extconf.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
fenv = control = false
|
5
|
+
|
6
|
+
if have_header('fenv.h')
|
7
|
+
fenv = true
|
8
|
+
#$defs.push "IEEE_FPU_FENV=1"
|
9
|
+
have_func('fesetprec','fenv.h')
|
10
|
+
end
|
11
|
+
|
12
|
+
if have_header('fpu_control.h')
|
13
|
+
control = true
|
14
|
+
#$defs.push "IEEE_FPU_CONTROL=1"
|
15
|
+
end
|
16
|
+
create_makefile("ieee_fpu_control") if fenv || control
|
17
|
+
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
|
3
|
+
#if HAVE_FENV_H
|
4
|
+
#include <fenv.h>
|
5
|
+
|
6
|
+
static VALUE mIEEE_FPU_fegetround(VALUE self)
|
7
|
+
{
|
8
|
+
return UINT2NUM(fegetround());
|
9
|
+
}
|
10
|
+
|
11
|
+
/*
|
12
|
+
* Set the FPU's rounding mode.
|
13
|
+
*/
|
14
|
+
static VALUE mIEEE_FPU_fesetround(VALUE self, VALUE mode)
|
15
|
+
{
|
16
|
+
fesetround(NUM2UINT(mode));
|
17
|
+
return UINT2NUM(fegetround());
|
18
|
+
}
|
19
|
+
|
20
|
+
#if HAVE_FESETPREC
|
21
|
+
static VALUE mIEEE_FPU_fegetprec(VALUE self)
|
22
|
+
{
|
23
|
+
return UINT2NUM(fegetprec());
|
24
|
+
}
|
25
|
+
static VALUE mIEEE_FPU_fesetprec(VALUE self, VALUE prec)
|
26
|
+
{
|
27
|
+
fesetprec(NUM2UINT(prec));
|
28
|
+
return UINT2NUM(fegetprec());
|
29
|
+
}
|
30
|
+
#endif
|
31
|
+
|
32
|
+
|
33
|
+
#endif
|
34
|
+
|
35
|
+
|
36
|
+
#if HAVE_FPU_CONTROL_H
|
37
|
+
|
38
|
+
#include <fpu_control.h>
|
39
|
+
|
40
|
+
static VALUE mIEEE_FPU_fpu_getround(VALUE self)
|
41
|
+
{
|
42
|
+
fpu_control_t mask = (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO);
|
43
|
+
fpu_control_t c;
|
44
|
+
_FPU_GETCW(c);
|
45
|
+
return UINT2NUM(c & mask);
|
46
|
+
}
|
47
|
+
|
48
|
+
static VALUE mIEEE_FPU_fpu_setround(VALUE self, VALUE mode)
|
49
|
+
{
|
50
|
+
fpu_control_t mask = (_FPU_RC_NEAREST|_FPU_RC_DOWN|_FPU_RC_UP|_FPU_RC_ZERO);
|
51
|
+
fpu_control_t c, new_c;
|
52
|
+
_FPU_GETCW(c);
|
53
|
+
new_c = c;
|
54
|
+
new_c &= ~mask;
|
55
|
+
new_c |= NUM2UINT(mode);
|
56
|
+
_FPU_SETCW(new_c);
|
57
|
+
return UINT2NUM(c & mask);
|
58
|
+
}
|
59
|
+
|
60
|
+
static VALUE mIEEE_FPU_fpu_getprec(VALUE self)
|
61
|
+
{
|
62
|
+
fpu_control_t mask = (_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE);
|
63
|
+
fpu_control_t c;
|
64
|
+
_FPU_GETCW(c);
|
65
|
+
return UINT2NUM(c & mask);
|
66
|
+
}
|
67
|
+
static VALUE mIEEE_FPU_fpu_setprec(VALUE self, VALUE prec)
|
68
|
+
{
|
69
|
+
fpu_control_t mask = (_FPU_EXTENDED|_FPU_DOUBLE|_FPU_SINGLE);
|
70
|
+
fpu_control_t c, new_c;
|
71
|
+
_FPU_GETCW(c);
|
72
|
+
new_c = c;
|
73
|
+
new_c &= ~mask;
|
74
|
+
new_c |= NUM2UINT(prec);
|
75
|
+
_FPU_SETCW(new_c);
|
76
|
+
return UINT2NUM(c & mask);
|
77
|
+
}
|
78
|
+
|
79
|
+
#endif
|
80
|
+
|
81
|
+
static VALUE mIEEE_FPU;
|
82
|
+
|
83
|
+
void Init_ieee_fpu_control() {
|
84
|
+
mIEEE_FPU = rb_define_module("IEEE_FPU");
|
85
|
+
|
86
|
+
#if HAVE_FPU_CONTROL_H
|
87
|
+
rb_define_const(mIEEE_FPU, "FPU_RC_NEAREST", UINT2NUM(_FPU_RC_NEAREST));
|
88
|
+
rb_define_const(mIEEE_FPU, "FPU_RC_DOWN", UINT2NUM(_FPU_RC_DOWN));
|
89
|
+
rb_define_const(mIEEE_FPU, "FPU_RC_UP", UINT2NUM(_FPU_RC_UP));
|
90
|
+
rb_define_const(mIEEE_FPU, "FPU_RC_ZERO", UINT2NUM(_FPU_RC_ZERO));
|
91
|
+
|
92
|
+
rb_define_module_function(mIEEE_FPU, "fpu_getround", mIEEE_FPU_fpu_getround, 0);
|
93
|
+
rb_define_module_function(mIEEE_FPU, "fpu_setround", mIEEE_FPU_fpu_setround, 1);
|
94
|
+
|
95
|
+
rb_define_const(mIEEE_FPU, "FPU_EXTENDED", UINT2NUM(_FPU_EXTENDED));
|
96
|
+
rb_define_const(mIEEE_FPU, "FPU_DOUBLE", UINT2NUM(_FPU_DOUBLE));
|
97
|
+
rb_define_const(mIEEE_FPU, "FPU_SINGLE", UINT2NUM(_FPU_SINGLE));
|
98
|
+
|
99
|
+
rb_define_module_function(mIEEE_FPU, "fpu_getprec", mIEEE_FPU_fpu_getprec, 0);
|
100
|
+
rb_define_module_function(mIEEE_FPU, "fpu_setprec", mIEEE_FPU_fpu_setprec, 1);
|
101
|
+
#endif
|
102
|
+
|
103
|
+
#if HAVE_FENV_H
|
104
|
+
rb_define_const(mIEEE_FPU, "FE_DOWNWARD", UINT2NUM(FE_DOWNWARD));
|
105
|
+
rb_define_const(mIEEE_FPU, "FE_TONEAREST", UINT2NUM(FE_TONEAREST));
|
106
|
+
rb_define_const(mIEEE_FPU, "FE_TOWARDZERO", UINT2NUM(FE_TOWARDZERO));
|
107
|
+
rb_define_const(mIEEE_FPU, "FE_UPWARD", UINT2NUM(FE_UPWARD));
|
108
|
+
|
109
|
+
rb_define_module_function(mIEEE_FPU, "fegetround", mIEEE_FPU_fegetround, 0);
|
110
|
+
rb_define_module_function(mIEEE_FPU, "fesetround", mIEEE_FPU_fesetround, 1);
|
111
|
+
|
112
|
+
#if HAVE_FESETPREC
|
113
|
+
rb_define_const(mIEEE_FPU, "FE_FLTPREC", UINT2NUM(FE_FLTPREC));
|
114
|
+
rb_define_const(mIEEE_FPU, "FE_DBLPREC", UINT2NUM(FE_DBLPREC));
|
115
|
+
rb_define_const(mIEEE_FPU, "FE_LDBLPREC", UINT2NUM(FE_LDBLPREC));
|
116
|
+
|
117
|
+
rb_define_module_function(mIEEE_FPU, "fegetprec", mIEEE_FPU_fegetprec, 0);
|
118
|
+
rb_define_module_function(mIEEE_FPU, "fesetprec", mIEEE_FPU_fesetprec, 1);
|
119
|
+
#endif
|
120
|
+
#endif
|
121
|
+
}
|
data/ieee-fpu.gemspec
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "ieee-fpu"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Javier Goizueta"]
|
12
|
+
s.date = "2012-09-28"
|
13
|
+
s.description = "Control of IEEE compliant FPUs rounding mode and precision"
|
14
|
+
s.email = "jgoizueta@gmail.com"
|
15
|
+
s.extensions = ["ext/extconf.rb"]
|
16
|
+
s.extra_rdoc_files = [
|
17
|
+
"LICENSE.txt",
|
18
|
+
"README.rdoc"
|
19
|
+
]
|
20
|
+
s.files = [
|
21
|
+
".document",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.rdoc",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"ext/extconf.rb",
|
29
|
+
"ext/ieee_fpu_control.c",
|
30
|
+
"ieee-fpu.gemspec",
|
31
|
+
"lib/ieee-fpu.rb",
|
32
|
+
"test/helper.rb",
|
33
|
+
"test/test_ieee-fpu.rb"
|
34
|
+
]
|
35
|
+
s.homepage = "http://github.com/jgoizueta/ieee-fpu"
|
36
|
+
s.licenses = ["MIT"]
|
37
|
+
s.require_paths = ["lib"]
|
38
|
+
s.rubygems_version = "1.8.23"
|
39
|
+
s.summary = "Control of IEEE compliant FPUs rounding mode and precision"
|
40
|
+
|
41
|
+
if s.respond_to? :specification_version then
|
42
|
+
s.specification_version = 3
|
43
|
+
|
44
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
47
|
+
s.add_development_dependency(%q<bundler>, ["~> 1"])
|
48
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.4"])
|
49
|
+
s.add_development_dependency(%q<flt>, [">= 0"])
|
50
|
+
else
|
51
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
52
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
53
|
+
s.add_dependency(%q<bundler>, ["~> 1"])
|
54
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
55
|
+
s.add_dependency(%q<flt>, [">= 0"])
|
56
|
+
end
|
57
|
+
else
|
58
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
59
|
+
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
60
|
+
s.add_dependency(%q<bundler>, ["~> 1"])
|
61
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.4"])
|
62
|
+
s.add_dependency(%q<flt>, [">= 0"])
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
data/lib/ieee-fpu.rb
ADDED
@@ -0,0 +1,424 @@
|
|
1
|
+
# IEEE_FPU -- IEEE FPU control
|
2
|
+
# Javier Goizueta 2007
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'ieee_fpu_control'
|
6
|
+
IEEE_FPU_FENV = IEEE_FPU.respond_to?(:fesetround)
|
7
|
+
IEEE_FPU_CONTROL = IEEE_FPU.respond_to?(:fpu_setprec)
|
8
|
+
rescue LoadError
|
9
|
+
IEEE_FPU_FENV = false
|
10
|
+
IEEE_FPU_CONTROL = false
|
11
|
+
end
|
12
|
+
|
13
|
+
unless IEEE_FPU_FENV || IEEE_FPU_CONTROL
|
14
|
+
|
15
|
+
require 'Win32API'
|
16
|
+
|
17
|
+
# Control of IEEE compliant FPUs rounding mode
|
18
|
+
# and precision (if available).
|
19
|
+
# IEEE_FPU has two writeable properties:
|
20
|
+
# * rounding which has values :even, :up, :down and :zero
|
21
|
+
# * precision with values :single, :double and :extended
|
22
|
+
# The latter property is not available in all IEEE FPUs
|
23
|
+
# The scope method can be used to set up an scope in which
|
24
|
+
# FPU properties are modified; when the scope is exited
|
25
|
+
# the FPU state is restored.
|
26
|
+
# Examples:
|
27
|
+
# puts IEEE_FPU.rounding # -> even
|
28
|
+
# puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
29
|
+
# IEEE_FPU.scope {
|
30
|
+
# IEEE_FPU.rounding = :down
|
31
|
+
# puts IEEE_FPU.rounding # -> down
|
32
|
+
# puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
33
|
+
# }
|
34
|
+
# IEEE_FPU.scope { |fpu|
|
35
|
+
# fpu.rounding = :up
|
36
|
+
# puts IEEE_FPU.rounding # -> up
|
37
|
+
# puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.0000000000000002220
|
38
|
+
# }
|
39
|
+
# puts IEEE_FPU.rounding # -> even
|
40
|
+
# puts "%.20f"%(1.0+Float::EPSILON/2) # -> 1.00000000000000000000
|
41
|
+
#
|
42
|
+
# expr = '(3.2-2.0)-1.2'
|
43
|
+
# IEEE_FPU.scope {
|
44
|
+
# IEEE_FPU.precision = :single # -> 0.0
|
45
|
+
# puts eval(expr)
|
46
|
+
# }
|
47
|
+
# IEEE_FPU.scope {
|
48
|
+
# IEEE_FPU.precision = :double
|
49
|
+
# puts eval(expr) # -> 2.22044604925031e-16
|
50
|
+
# }
|
51
|
+
#
|
52
|
+
# Note: IEEE_FPU.precision=:extended has a very limited influence in Ruby
|
53
|
+
# because all results are casted to Float (double) values.
|
54
|
+
# Its effect is more noticeable in C/C++ extensions.
|
55
|
+
|
56
|
+
# FPU parameters can be assigneed passign a hash to the scope method:
|
57
|
+
# IEEE_FPU.scope(:precision=>:single) {
|
58
|
+
# puts eval(expr)
|
59
|
+
# }
|
60
|
+
# An array can be passed for one (only one) of the parameters;
|
61
|
+
# the block will be repeated with every value of the parameter
|
62
|
+
# and the results will be collected in an array.
|
63
|
+
# For example this checks the result of an expression in all
|
64
|
+
# the rounding modes:
|
65
|
+
# puts IEEE_FPU.scope(:rounding=>[:even,:up,:down,:zero]) {
|
66
|
+
# 1.0 + Float::EPSILON/2
|
67
|
+
# }.inspect
|
68
|
+
#
|
69
|
+
# Different parameters can be passed to each call of the block
|
70
|
+
# by assigning an array to :parameters
|
71
|
+
# For example, interval arithmetic could be implementes like this:
|
72
|
+
# def sum_intervals(i1,i2)
|
73
|
+
# IEEE_FPU.scope(:rounding=>[:down,:up],:parameters=>[0,1]) do |fpu,i|
|
74
|
+
# i1[i]+i2[i]
|
75
|
+
# end
|
76
|
+
# end
|
77
|
+
# i = sum_intervals([1.0]*2, [Float::EPSILON/2]*2)
|
78
|
+
|
79
|
+
|
80
|
+
module IEEE_FPU
|
81
|
+
|
82
|
+
class Error < StandardError
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.get_status
|
86
|
+
Controlfp.call(0,0)
|
87
|
+
end
|
88
|
+
def self.set_status(s)
|
89
|
+
Controlfp.call(s,MCW_DN|MCW_EM|MCW_IC|MCW_RC|MCW_PC)
|
90
|
+
end
|
91
|
+
def self.scope(assignments={})
|
92
|
+
v = nil
|
93
|
+
s = get_status
|
94
|
+
prc = assignments[:precision]
|
95
|
+
rnd = assignments[:rounding]
|
96
|
+
self.precision = prc if prc && !(Array===prc)
|
97
|
+
self.rounding =rnd if rnd && !(Array===rnd)
|
98
|
+
if Array===prc
|
99
|
+
param = assignments[:parameters] || [nil]*prc.size
|
100
|
+
v = []
|
101
|
+
i = 0
|
102
|
+
prc.each do |p|
|
103
|
+
self.precision = p
|
104
|
+
v << yield(self, param[i])
|
105
|
+
i += 1
|
106
|
+
end
|
107
|
+
elsif Array===rnd
|
108
|
+
param = assignments[:parameters] || [nil]*rnd.size
|
109
|
+
v = []
|
110
|
+
i = 0
|
111
|
+
rnd.each do |r|
|
112
|
+
self.rounding = r
|
113
|
+
v << yield(self, param[i])
|
114
|
+
i += 1
|
115
|
+
end
|
116
|
+
else
|
117
|
+
v = yield(self)
|
118
|
+
end
|
119
|
+
v
|
120
|
+
ensure
|
121
|
+
set_status s
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.precision
|
125
|
+
v = get_status & MCW_PC
|
126
|
+
p = nil
|
127
|
+
case v
|
128
|
+
when PC_24
|
129
|
+
p = :single
|
130
|
+
when PC_53
|
131
|
+
p = :double
|
132
|
+
when PC_64
|
133
|
+
p = :extended
|
134
|
+
end
|
135
|
+
p
|
136
|
+
end
|
137
|
+
def self.precision=(p)
|
138
|
+
v = nil
|
139
|
+
case p
|
140
|
+
when :single, 24
|
141
|
+
v = PC_24
|
142
|
+
when :double, 53
|
143
|
+
v = PC_53
|
144
|
+
when :extended, 64, 112
|
145
|
+
v = PC_64
|
146
|
+
else
|
147
|
+
raise Error, "Invalid precision #{p.inspect}"
|
148
|
+
end
|
149
|
+
Controlfp.call(v,MCW_PC) unless v.nil?
|
150
|
+
p
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.rounding
|
154
|
+
v = get_status & MCW_RC
|
155
|
+
r = nil
|
156
|
+
case v
|
157
|
+
when RC_UP
|
158
|
+
r = :up
|
159
|
+
when RC_DOWN
|
160
|
+
r = :down
|
161
|
+
when RC_CHOP
|
162
|
+
r = :zero
|
163
|
+
when RC_NEAR
|
164
|
+
r = :even
|
165
|
+
end
|
166
|
+
r
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.rounding=(r)
|
170
|
+
v = nil
|
171
|
+
case r
|
172
|
+
when :up, :plus_infinity, :positive_infinity
|
173
|
+
v = RC_UP
|
174
|
+
when :down, :minus_inifinity, :negative_infinity
|
175
|
+
v = RC_DOWN
|
176
|
+
when :zero, :truncate, :chop
|
177
|
+
v = RC_CHOP
|
178
|
+
when :even, :near, :unbiased
|
179
|
+
v = RC_NEAR
|
180
|
+
else
|
181
|
+
raise Error, "Invalid rounding mode #{r}"
|
182
|
+
end
|
183
|
+
Controlfp.call(v,MCW_RC) unless v.nil?
|
184
|
+
r
|
185
|
+
end
|
186
|
+
|
187
|
+
def self.supported_precisions
|
188
|
+
[:single, :double, :extended]
|
189
|
+
end
|
190
|
+
|
191
|
+
|
192
|
+
Controlfp = Win32API.new('msvcrt', '_controlfp', 'II', 'I')
|
193
|
+
MCW_DN = 0x03000000 # Denormal control mask
|
194
|
+
DN_SAVE = 0x00000000
|
195
|
+
DN_FLUSH = 0x01000000
|
196
|
+
MCW_EM = 0x0008001F # Interrupt exception mask
|
197
|
+
EM_INVALID = 0x00000010
|
198
|
+
EM_DENORMAL = 0x00080000
|
199
|
+
EM_ZERODIVIDE = 0x00000008
|
200
|
+
EM_OVERFLOW = 0x00000004
|
201
|
+
EM_UNDERFLOW = 0x00000002
|
202
|
+
EM_INEXACT = 0x00000001
|
203
|
+
MCW_IC = 0x00040000 # Infinity control mask
|
204
|
+
IC_AFFINE = 0x00040000
|
205
|
+
IC_PROJECTIVE = 0x00000000
|
206
|
+
MCW_RC = 0x00000300 # Rounding control mask
|
207
|
+
RC_CHOP = 0x00000300
|
208
|
+
RC_UP = 0x00000200
|
209
|
+
RC_DOWN = 0x00000100
|
210
|
+
RC_NEAR = 0x00000000
|
211
|
+
MCW_PC = 0x00030000 # Precision control mask
|
212
|
+
PC_24 = 0x00020000 # 24 bits
|
213
|
+
PC_53 = 0x00010000 # 53 bits
|
214
|
+
PC_64 = 0x00000000 # 64 bits
|
215
|
+
end
|
216
|
+
|
217
|
+
else
|
218
|
+
|
219
|
+
# use ieee_fpu extension
|
220
|
+
module IEEE_FPU
|
221
|
+
|
222
|
+
class Error < StandardError
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.get_status
|
226
|
+
status = []
|
227
|
+
if IEEE_FPU_FENV
|
228
|
+
status << fegetround
|
229
|
+
if self.respond_to?(:fegetprec)
|
230
|
+
status << fegetprec
|
231
|
+
elsif IEEE_FPU_CONTROL
|
232
|
+
status << fpu_getprec
|
233
|
+
end
|
234
|
+
else
|
235
|
+
status << fpu_getround
|
236
|
+
status << fpu_getprec
|
237
|
+
end
|
238
|
+
status
|
239
|
+
end
|
240
|
+
def self.set_status(s)
|
241
|
+
r_s,p_s = s
|
242
|
+
if IEEE_FPU_FENV
|
243
|
+
fesetround r_s
|
244
|
+
if self.respond_to?(:fesetprec)
|
245
|
+
fesetprec p_s
|
246
|
+
elsif IEEE_FPU_CONTROL
|
247
|
+
fpu_setprec p_s
|
248
|
+
end
|
249
|
+
else
|
250
|
+
fpu_setround r_s
|
251
|
+
fpu_setprec p_s
|
252
|
+
end
|
253
|
+
|
254
|
+
end
|
255
|
+
|
256
|
+
def self.scope(assignments={})
|
257
|
+
v = nil
|
258
|
+
s = get_status
|
259
|
+
prc = assignments[:precision]
|
260
|
+
rnd = assignments[:rounding]
|
261
|
+
self.precision = prc if prc && !(Array===prc)
|
262
|
+
self.rounding =rnd if rnd && !(Array===rnd)
|
263
|
+
if Array===prc
|
264
|
+
param = assignments[:parameters] || [nil]*prc.size
|
265
|
+
v = []
|
266
|
+
i = 0
|
267
|
+
prc.each do |p|
|
268
|
+
self.precision = p
|
269
|
+
v << yield(self, param[i])
|
270
|
+
i += 1
|
271
|
+
end
|
272
|
+
elsif Array===rnd
|
273
|
+
param = assignments[:parameters] || [nil]*rnd.size
|
274
|
+
v = []
|
275
|
+
i = 0
|
276
|
+
rnd.each do |r|
|
277
|
+
self.rounding = r
|
278
|
+
v << yield(self, param[i])
|
279
|
+
i += 1
|
280
|
+
end
|
281
|
+
else
|
282
|
+
v = yield(self)
|
283
|
+
end
|
284
|
+
v
|
285
|
+
ensure
|
286
|
+
set_status s
|
287
|
+
end
|
288
|
+
|
289
|
+
def self.precision
|
290
|
+
p = nil
|
291
|
+
if IEEE_FPU_FENV && self.respond_to?(:fegetprec)
|
292
|
+
v = fegetprec
|
293
|
+
case v
|
294
|
+
when FE_FLTPREC
|
295
|
+
p = :single
|
296
|
+
when FE_DBLPREC
|
297
|
+
p = :double
|
298
|
+
when FE_LDBLPREC
|
299
|
+
p = :extended
|
300
|
+
end
|
301
|
+
elsif IEEE_FPU_CONTROL
|
302
|
+
v = fpu_getprec
|
303
|
+
case v
|
304
|
+
when FPU_SINGLE
|
305
|
+
p = :single
|
306
|
+
when FPU_DOUBLE
|
307
|
+
p = :double
|
308
|
+
when FPU_EXTENDED
|
309
|
+
p = :extended
|
310
|
+
end
|
311
|
+
else
|
312
|
+
p = :double
|
313
|
+
end
|
314
|
+
p
|
315
|
+
end
|
316
|
+
def self.precision=(p)
|
317
|
+
if IEEE_FPU_FENV && self.respond_to?(:fesetprec)
|
318
|
+
v = nil
|
319
|
+
case p
|
320
|
+
when :single,24
|
321
|
+
v = FE_FLTPREC
|
322
|
+
when :double,53
|
323
|
+
v = FE_DBLPREC
|
324
|
+
when :extended,64,112
|
325
|
+
v = FE_LDBLPREC
|
326
|
+
else
|
327
|
+
raise Error, "Invalid precision #{p.inspect}"
|
328
|
+
end
|
329
|
+
fesetprec v
|
330
|
+
elsif IEEE_FPU_CONTROL
|
331
|
+
v = nil
|
332
|
+
case p
|
333
|
+
when :single,24
|
334
|
+
v = FPU_SINGLE
|
335
|
+
when :double,53
|
336
|
+
v = FPU_DOUBLE
|
337
|
+
when :extended,64,112
|
338
|
+
v = FPU_EXTENDED
|
339
|
+
else
|
340
|
+
raise Error, "Invalid precision #{p.inspect}"
|
341
|
+
end
|
342
|
+
fpu_setprec v
|
343
|
+
else
|
344
|
+
raise Error, "Precision not supported #{p.inspect}" if p!=:double
|
345
|
+
end
|
346
|
+
p
|
347
|
+
end
|
348
|
+
|
349
|
+
def self.rounding
|
350
|
+
if IEEE_FPU_FENV
|
351
|
+
v = fegetround
|
352
|
+
r = nil
|
353
|
+
case v
|
354
|
+
when FE_UPWARD
|
355
|
+
r = :up
|
356
|
+
when FE_DOWNWARD
|
357
|
+
r = :down
|
358
|
+
when FE_TOWARDZERO
|
359
|
+
r = :zero
|
360
|
+
when FE_TONEAREST
|
361
|
+
r = :even
|
362
|
+
end
|
363
|
+
else
|
364
|
+
v = fpu_getround
|
365
|
+
r = nil
|
366
|
+
case v
|
367
|
+
when FPU_RC_UP
|
368
|
+
r = :up
|
369
|
+
when FPU_RC_DOWN
|
370
|
+
r = :down
|
371
|
+
when FPU_RC_ZERO
|
372
|
+
r = :zero
|
373
|
+
when FPU_RC_NEAREST
|
374
|
+
r = :even
|
375
|
+
end
|
376
|
+
end
|
377
|
+
r
|
378
|
+
end
|
379
|
+
|
380
|
+
def self.rounding=(r)
|
381
|
+
v = nil
|
382
|
+
if IEEE_FPU_FENV
|
383
|
+
case r
|
384
|
+
when :up, :plus_infinity, :positive_infinity
|
385
|
+
v = FE_UPWARD
|
386
|
+
when :down, :minus_inifinity, :negative_infinity
|
387
|
+
v = FE_DOWNWARD
|
388
|
+
when :zero, :truncate, :chop
|
389
|
+
v = FE_TOWARDZERO
|
390
|
+
when :even, :near, :unbiased
|
391
|
+
v = FE_TONEAREST
|
392
|
+
else
|
393
|
+
raise Error, "Invalid rounding mode #{r}"
|
394
|
+
end
|
395
|
+
fesetround v unless v.nil?
|
396
|
+
else
|
397
|
+
case r
|
398
|
+
when :up, :plus_infinity, :positive_infinity
|
399
|
+
v = FPU_RC_UP
|
400
|
+
when :down, :minus_inifinity, :negative_infinity
|
401
|
+
v = FPU_RC_DOWN
|
402
|
+
when :zero, :truncate, :chop
|
403
|
+
v = FPU_RC_ZERO
|
404
|
+
when :even, :near, :unbiased
|
405
|
+
v = FPU_RC_NEAREST
|
406
|
+
else
|
407
|
+
raise Error, "Invalid rounding mode #{r}"
|
408
|
+
end
|
409
|
+
fpu_setround v unless v.nil?
|
410
|
+
end
|
411
|
+
r
|
412
|
+
end
|
413
|
+
|
414
|
+
def self.supported_precisions
|
415
|
+
if (IEEE_FPU_FENV && self.respond_to?(:fesetprec)) || IEEE_FPU_CONTROL
|
416
|
+
[:single, :double, :extened]
|
417
|
+
else
|
418
|
+
[:double]
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
require 'flt'
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :development)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
require 'test/unit'
|
12
|
+
require 'shoulda'
|
13
|
+
|
14
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'ext'))
|
15
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
16
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
17
|
+
require 'ieee-fpu'
|
18
|
+
|
19
|
+
class Test::Unit::TestCase
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def test_operation(description, parameters)
|
24
|
+
|
25
|
+
cons = lambda{|x| Float(x)}
|
26
|
+
result = IEEE_FPU.scope(parameters){yield(cons)}
|
27
|
+
|
28
|
+
binnum_parameters = {
|
29
|
+
:rounding => {
|
30
|
+
:even=>:half_even,
|
31
|
+
:down=>:floor,
|
32
|
+
:up=>:ceiling,
|
33
|
+
:zero=>:down
|
34
|
+
}[parameters[:rounding]],
|
35
|
+
:precision => {
|
36
|
+
:single=>24,
|
37
|
+
:double=>53,
|
38
|
+
:extended=>64
|
39
|
+
}[parameters[:rounding]]
|
40
|
+
}
|
41
|
+
|
42
|
+
cons = Flt::BinNum
|
43
|
+
base_context = Flt::BinNum::FloatContext
|
44
|
+
reference = Flt::BinNum.context(base_context, binnum_parameters){yield(cons)}.to_f
|
45
|
+
|
46
|
+
assert_equal reference, result, description
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestIeeeFpu < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "round correctly for each precision supported" do
|
6
|
+
|
7
|
+
IEEE_FPU.supported_precisions.each do |precision|
|
8
|
+
[:up, :down, :zero, :even].each do |rounding|
|
9
|
+
parameters = {
|
10
|
+
:rounding => rounding,
|
11
|
+
:precision => precision
|
12
|
+
}
|
13
|
+
|
14
|
+
test_operation("#{precision} #{rounding} : (2000.0/60)*60/1000 - 2", parameters) do |num|
|
15
|
+
(num[2000]/60)*num[60]/1000 - num[2]
|
16
|
+
end
|
17
|
+
|
18
|
+
test_operation("#{precision} #{rounding} : 1.0+Float::EPSILON/2", parameters) do |num|
|
19
|
+
num[1] + num[Float::EPSILON/2]
|
20
|
+
end
|
21
|
+
|
22
|
+
test_operation("#{precision} #{rounding} : 1.0-Float::EPSILON/4", parameters) do |num|
|
23
|
+
num[1] - num[Float::EPSILON/4]
|
24
|
+
end
|
25
|
+
|
26
|
+
test_operation("#{precision} #{rounding} : -1.0-Float::EPSILON/2", parameters) do |num|
|
27
|
+
num[-1] - num[Float::EPSILON/2]
|
28
|
+
end
|
29
|
+
|
30
|
+
test_operation("#{precision} #{rounding} : -1.0+Float::EPSILON/4", parameters) do |num|
|
31
|
+
num[-1] + num[Float::EPSILON/4]
|
32
|
+
end
|
33
|
+
|
34
|
+
test_operation("#{precision} #{rounding} : 10/9.0-1.0-1/9.0", parameters) do |num|
|
35
|
+
num[10]/num[9]-num[1]-num[1]/num[9]
|
36
|
+
end
|
37
|
+
|
38
|
+
test_operation("#{precision} #{rounding} : -10/9.0+1.0+1/9.0", parameters) do |num|
|
39
|
+
num[-10]/num[9]+num[1]+num[1]/num[9]
|
40
|
+
end
|
41
|
+
|
42
|
+
test_operation("#{precision} #{rounding} : 1-(4.0/3-1)*3", parameters) do |num|
|
43
|
+
num[1] - (num[4]/num[3]-num[1])*num[3]
|
44
|
+
end
|
45
|
+
|
46
|
+
test_operation("#{precision} #{rounding} : (4.0/3-1)*3 - 1", parameters) do |num|
|
47
|
+
(num[4]/num[3]-num[1])*num[3] - num[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ieee-fpu
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Javier Goizueta
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: shoulda
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rdoc
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '3.12'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '3.12'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: jeweler
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 1.8.4
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.8.4
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: flt
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Control of IEEE compliant FPUs rounding mode and precision
|
95
|
+
email: jgoizueta@gmail.com
|
96
|
+
executables: []
|
97
|
+
extensions:
|
98
|
+
- ext/extconf.rb
|
99
|
+
extra_rdoc_files:
|
100
|
+
- LICENSE.txt
|
101
|
+
- README.rdoc
|
102
|
+
files:
|
103
|
+
- .document
|
104
|
+
- Gemfile
|
105
|
+
- Gemfile.lock
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.rdoc
|
108
|
+
- Rakefile
|
109
|
+
- VERSION
|
110
|
+
- ext/extconf.rb
|
111
|
+
- ext/ieee_fpu_control.c
|
112
|
+
- ieee-fpu.gemspec
|
113
|
+
- lib/ieee-fpu.rb
|
114
|
+
- test/helper.rb
|
115
|
+
- test/test_ieee-fpu.rb
|
116
|
+
homepage: http://github.com/jgoizueta/ieee-fpu
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
none: false
|
125
|
+
requirements:
|
126
|
+
- - ! '>='
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
segments:
|
130
|
+
- 0
|
131
|
+
hash: 3801110420751279703
|
132
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
+
none: false
|
134
|
+
requirements:
|
135
|
+
- - ! '>='
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
requirements: []
|
139
|
+
rubyforge_project:
|
140
|
+
rubygems_version: 1.8.23
|
141
|
+
signing_key:
|
142
|
+
specification_version: 3
|
143
|
+
summary: Control of IEEE compliant FPUs rounding mode and precision
|
144
|
+
test_files: []
|