Skip to content

Commit fe9d6ae

Browse files
mbrubeckbrson
authored andcommitted
---
yaml --- r: 6050 b: refs/heads/master c: 8c51d4b h: refs/heads/master v: v3
1 parent 2f9338f commit fe9d6ae

File tree

3 files changed

+44
-5
lines changed

3 files changed

+44
-5
lines changed

[refs]

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 0bf10d84e2ec78c129f3fd04ed080d2d2038680f
2+
refs/heads/master: 8c51d4b002b2743fd50bc715429265aaaf482762

trunk/src/lib/float.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ This function accepts strings such as
4848
* "5."
4949
* ".5", or, equivalently, "0.5"
5050
51+
Leading and trailing whitespace are ignored.
52+
5153
Parameters:
5254
5355
num - A string, possibly empty.
@@ -58,6 +60,8 @@ Returns:
5860
Otherwise, the floating-point number represented [num].
5961
*/
6062
fn from_str(num: str) -> float {
63+
num = str::trim(num);
64+
6165
let pos = 0u; //Current byte position in the string.
6266
//Used to walk the string in O(n).
6367
let len = str::byte_len(num); //Length of the string, in bytes.
@@ -66,6 +70,12 @@ fn from_str(num: str) -> float {
6670
let total = 0f; //Accumulated result
6771
let c = 'z'; //Latest char.
6872

73+
//The string must start with one of the following characters.
74+
alt str::char_at(num, 0u) {
75+
'-' | '+' | '0' to '9' | '.' {}
76+
_ { ret NaN(); }
77+
}
78+
6979
//Determine if first char is '-'/'+'. Set [pos] and [neg] accordingly.
7080
let neg = false; //Sign of the result
7181
alt str::char_at(num, 0u) {
@@ -89,9 +99,12 @@ fn from_str(num: str) -> float {
8999
total = total * 10f;
90100
total += ((c as int) - ('0' as int)) as float;
91101
}
92-
_ {
102+
'.' | 'e' | 'E' {
93103
break;
94104
}
105+
_ {
106+
ret NaN();
107+
}
95108
}
96109
}
97110

@@ -106,9 +119,12 @@ fn from_str(num: str) -> float {
106119
decimal /= 10.f;
107120
total += (((c as int) - ('0' as int)) as float)*decimal;
108121
}
109-
_ {
122+
'e' | 'E' {
110123
break;
111124
}
125+
_ {
126+
ret NaN();
127+
}
112128
}
113129
}
114130
}
@@ -132,7 +148,6 @@ fn from_str(num: str) -> float {
132148
while(pos < len) {
133149
let char_range = str::char_range_at(num, pos);
134150
c = char_range.ch;
135-
pos = char_range.next;
136151
alt c {
137152
'0' | '1' | '2' | '3' | '4' | '5' | '6'| '7' | '8' | '9' {
138153
exponent *= 10u;
@@ -142,6 +157,7 @@ fn from_str(num: str) -> float {
142157
break;
143158
}
144159
}
160+
pos = char_range.next;
145161
}
146162
let multiplier = pow_uint_to_uint_as_float(10u, exponent);
147163
//Note: not [int::pow], otherwise, we'll quickly
@@ -151,6 +167,8 @@ fn from_str(num: str) -> float {
151167
} else {
152168
total = total * multiplier;
153169
}
170+
} else {
171+
ret NaN();
154172
}
155173
}
156174

trunk/src/test/stdtest/float.rs

+22-1
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,39 @@ import std::float;
33

44
#[test]
55
fn test_from_str() {
6+
assert ( float::from_str("3") == 3. );
7+
assert ( float::from_str(" 3 ") == 3. );
68
assert ( float::from_str("3.14") == 3.14 );
79
assert ( float::from_str("+3.14") == 3.14 );
810
assert ( float::from_str("-3.14") == -3.14 );
911
assert ( float::from_str("2.5E10") == 25000000000. );
1012
assert ( float::from_str("2.5e10") == 25000000000. );
1113
assert ( float::from_str("25000000000.E-10") == 2.5 );
1214
assert ( float::from_str("") == 0. );
13-
assert ( float::isNaN(float::from_str(" ")) );
1415
assert ( float::from_str(".") == 0. );
16+
assert ( float::from_str(".e1") == 0. );
17+
assert ( float::from_str(".e-1") == 0. );
1518
assert ( float::from_str("5.") == 5. );
1619
assert ( float::from_str(".5") == 0.5 );
1720
assert ( float::from_str("0.5") == 0.5 );
21+
assert ( float::from_str("0.5 ") == 0.5 );
22+
assert ( float::from_str(" 0.5 ") == 0.5 );
23+
assert ( float::from_str(" -.5 ") == -0.5 );
24+
assert ( float::from_str(" -.5 ") == -0.5 );
25+
assert ( float::from_str(" -5 ") == -5. );
26+
27+
assert ( float::isNaN(float::from_str("x")) );
28+
assert ( float::from_str(" ") == 0. );
29+
assert ( float::from_str(" ") == 0. );
30+
assert ( float::from_str(" 0.5") == 0.5 );
31+
assert ( float::from_str(" 0.5 ") == 0.5 );
32+
assert ( float::from_str(" .1 ") == 0.1 );
33+
assert ( float::isNaN(float::from_str("e")) );
34+
assert ( float::isNaN(float::from_str("E")) );
35+
assert ( float::isNaN(float::from_str("E1")) );
36+
assert ( float::isNaN(float::from_str("1e1e1")) );
37+
assert ( float::isNaN(float::from_str("1e1.1")) );
38+
assert ( float::isNaN(float::from_str("1e1-1")) );
1839
}
1940

2041
#[test]

0 commit comments

Comments
 (0)