lexidecimal 0.0.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.
- data/README +13 -0
- data/lib/lexidecimal.rb +105 -0
- metadata +56 -0
data/README
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Lexidecimal
|
2
|
+
|
3
|
+
(lexically-stortable string representations of BigDecimal)
|
4
|
+
|
5
|
+
Ideas are taken from here:
|
6
|
+
|
7
|
+
http://www.zanopha.com/docs/elen.ps
|
8
|
+
|
9
|
+
Paper was suggested by this guy:
|
10
|
+
|
11
|
+
http://groups.google.com/group/google-appengine-java/browse_thread/thread/684b6aa3e4966e0b/f1a4a22ca667b569?lnk=gst&q=bigdecimal
|
12
|
+
|
13
|
+
However, I'm not sure "use as you wish" is legally binding, and I wanted a pure-Ruby version anyway. I also wanted to understand how it actually worked. The strings generated by this library DO NOT match the strings generated by the Java version linked to above. I doubt either can parse the other's strings.
|
data/lib/lexidecimal.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'bigdecimal'
|
2
|
+
|
3
|
+
module Lexidecimal
|
4
|
+
MINUS = '-'.freeze
|
5
|
+
PLUS = 'p'.freeze
|
6
|
+
|
7
|
+
def self.invert string
|
8
|
+
string.each_char.map{|d| 9-d.to_i}.join
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.int_to_string num, sign=nil, negative=nil
|
12
|
+
return '0' if num == 0
|
13
|
+
|
14
|
+
if sign.nil?
|
15
|
+
if num < 0
|
16
|
+
sign = MINUS
|
17
|
+
negative = true
|
18
|
+
num = -num
|
19
|
+
else
|
20
|
+
sign = PLUS
|
21
|
+
negative = false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
string = num.to_s
|
26
|
+
string = self.invert string if negative
|
27
|
+
|
28
|
+
length = string.length
|
29
|
+
if length > 1
|
30
|
+
"#{sign}#{self.int_to_string length, sign, negative}#{string}"
|
31
|
+
else
|
32
|
+
"#{sign}#{string}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.decimal_to_string num
|
37
|
+
sign, digits, base, exponent = num.split
|
38
|
+
|
39
|
+
return '0' if digits == '0'
|
40
|
+
|
41
|
+
negative = (sign < 1)
|
42
|
+
if negative
|
43
|
+
digits = self.invert digits
|
44
|
+
sign = MINUS
|
45
|
+
antisign = PLUS
|
46
|
+
else
|
47
|
+
sign = PLUS
|
48
|
+
antisign = MINUS
|
49
|
+
end
|
50
|
+
|
51
|
+
"#{sign}#{self.int_to_string(negative ? -exponent : exponent)}#{digits}#{antisign}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.string_to_int string
|
55
|
+
self.enum_to_int string.each_char
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.enum_to_int enum
|
59
|
+
sign = enum.next
|
60
|
+
return 0 if sign == '0'
|
61
|
+
count = 0
|
62
|
+
while (cur = enum.next) == sign
|
63
|
+
count += 1
|
64
|
+
end
|
65
|
+
negative = (sign == MINUS)
|
66
|
+
length = cur.to_i
|
67
|
+
length = 9 - length if negative
|
68
|
+
count.times do
|
69
|
+
new_length = 0
|
70
|
+
length.times do
|
71
|
+
new_length *= 10
|
72
|
+
digit = enum.next.to_i
|
73
|
+
digit = 9 - digit if negative
|
74
|
+
new_length += digit
|
75
|
+
end
|
76
|
+
length = new_length
|
77
|
+
end
|
78
|
+
negative ? -length : length
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.string_to_decimal string
|
82
|
+
self.enum_to_decimal string.each_char
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.enum_to_decimal enum
|
86
|
+
sign = enum.next
|
87
|
+
negative = (sign == MINUS)
|
88
|
+
antisign = (negative ? PLUS : MINUS)
|
89
|
+
|
90
|
+
exponent = self.enum_to_int enum
|
91
|
+
exponent = -exponent if negative
|
92
|
+
|
93
|
+
digits = ''
|
94
|
+
|
95
|
+
while (cur = enum.next) != antisign
|
96
|
+
if negative
|
97
|
+
digits << (9 - cur.to_i).to_s
|
98
|
+
else
|
99
|
+
digits << cur
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
BigDecimal.new "#{negative ? '-' : ''}0.#{digits}e#{exponent}"
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lexidecimal
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- David Masover
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-05-27 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: ninja@slaphack.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files: []
|
23
|
+
|
24
|
+
files:
|
25
|
+
- README
|
26
|
+
- lib/lexidecimal.rb
|
27
|
+
has_rdoc: false
|
28
|
+
homepage:
|
29
|
+
licenses: []
|
30
|
+
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: "0"
|
41
|
+
version:
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
version:
|
48
|
+
requirements: []
|
49
|
+
|
50
|
+
rubyforge_project:
|
51
|
+
rubygems_version: 1.3.5
|
52
|
+
signing_key:
|
53
|
+
specification_version: 3
|
54
|
+
summary: lexically-stortable string representations of BigDecimal
|
55
|
+
test_files: []
|
56
|
+
|