Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Make String#to_f returns 0.0 for strings with leading underscores #1662

Closed
wants to merge 2 commits into from

3 participants

@IPGlider
Collaborator

In Ruby 1.9.3

1.9.3p125 :001 > "_9".to_f
 => 0.0 

Before patch in Rubinius in 1.9 mode

rubinius-2.0.0dev :001 > "_9".to_f
 => 9.0 

After patch in Rubinius in 1.9 mode

rubinius-2.0.0dev :001 > "_9".to_f
 => 0.0 
@zaeleus
Collaborator

I've been working on a more robust fix for this, especially since the current implementation has no concept of strictness (besides the regex match in Kernel#Float).

#1613

@IPGlider
Collaborator

Didn't saw someone was working on this, your solution seems a lot more complicated than mine. I will take a look, maybe we can coordinate.

@jfirebaugh
Collaborator

#1613 was merged. Sorry about the duplicated work @IPGlider.

@jfirebaugh jfirebaugh closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 11, 2012
  1. @IPGlider
Commits on Apr 13, 2012
  1. @IPGlider

    Remove tag for passing spec

    IPGlider authored
This page is out of date. Refresh to see the latest.
Showing with 22 additions and 18 deletions.
  1. +0 −1  spec/tags/19/ruby/core/string/to_f_tags.txt
  2. +22 −17 vm/builtin/string.cpp
View
1  spec/tags/19/ruby/core/string/to_f_tags.txt
@@ -1 +0,0 @@
-fails:String#to_f returns 0 for strings with leading underscores
View
39 vm/builtin/string.cpp
@@ -921,31 +921,36 @@ namespace rubinius {
char *p, *n, *rest;
int e_seen = 0;
- p = ba;
- while(ISSPACE(*p)) p++;
- n = p;
+ if(!LANGUAGE_18_ENABLED(state) && *ba == '_') {
+ value = 0.0;
+ } else {
+ p = ba;
+ while(ISSPACE(*p)) p++;
+ n = p;
- while(*p) {
- if(*p == '_') {
- p++;
- } else {
- if(*p == 'e' || *p == 'E') {
- if(e_seen) {
+ while(*p) {
+ if(*p == '_') {
+ p++;
+ } else {
+ if(*p == 'e' || *p == 'E') {
+ if(e_seen) {
+ *n = 0;
+ break;
+ }
+ e_seen = 1;
+ } else if(!(ISDIGIT(*p) || *p == '.' || *p == '-' || *p == '+')) {
*n = 0;
break;
}
- e_seen = 1;
- } else if(!(ISDIGIT(*p) || *p == '.' || *p == '-' || *p == '+')) {
- *n = 0;
- break;
- }
- *n++ = *p++;
+ *n++ = *p++;
+ }
}
+ *n = 0;
+
+ value = ruby_strtod(ba, &rest);
}
- *n = 0;
- value = ruby_strtod(ba, &rest);
free(ba);
return value;
Something went wrong with that request. Please try again.