Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Sass doesn’t like foating point decimals. #111

Open
Darkwing371 opened this Issue · 15 comments
@Darkwing371

First: this issue has nothing to do with the Sass::Script::Number.Precision. That is fine!

Second: This is a re-post of my formerly opened issue in the sass/sass#694 since the problem is assumed to be Scout-related.


The past three hours I was going nuts seeing Sass 3.2.1 (Scout 0.7.1, Win 7 x64) calculating the same math operation with two different outcomes between two compilings. It’s insane!

I simply tried to convert centimeters to inches by doing:

  $cm: 1;
  $in: $cm / 2.54;

After saving (compiling), the outcome was: 0.3937, as one would expect.
After saving again, however the outcome was: 0.5. My boy, my boy!

And so Sass seems to choose the result at random, at every saving (compiling); but most of the time the wrong result as far as I could see.

It took me tree hours to narrow the problem down inside of my mixins.
What is going on now is pretty clear to see in my minified examples: sometimes Sass forgets, that there are some numbers present behind the decimal point. It calculates 1 / 2 = 0.5.

I wonder that so few people have this problem – am I the only one who noticed this?
It was hard to google for this.
I only found some related problems, also concerning floting points (maybe theres the same underlying problem):

#22
#41
#44
#103
#105

So far by the comments it seems to be narrowed down to that it is no promlem with Compass or Scout, it must be Sass itself. Although Sass-People were quick to say otherwise: sass/sass#694 (comment) they’re right …?


For the moment I found out that to abstain from typing floating points will solve this problem! Like so:

$cm: 1;
$factor: 254;
$factor: $factor / 100;
$in: $cm / $factor;

Luckily at least this is possible. Or shorter:

$cm: 1;
$in: $cm / 254 / 100;

So when a floating point occurs via "hidden calculation" inside of variables, this problem seems not to happen – so no one needs to be scared. Only when typed directly, then this weired loss of decimals occurs.

And notice whats also a problem:

$cm: 1;
$factor: 2.54;
$in: $cm / $factor;

Makes 0.5.
Almost all the time.
It seams that the first time Sass gets it right, all the other times Sass cancels the decimals.

Btw: this also occurs when multiplying, oder adding, or subtracting:

 $in: 1 + 2.54;

Makes 3. This is just ridiculous.


So: do not type floating point decimals until this is fixed.


For everyone whos encountering this error too, I wrote a little workaround-function to fix this.

  @function floatfix($value: 100, $decimals: 2) {
      @for $i from 1 through $decimals { $value: $value / 10; }
  @return $value;
  }

Usage:

$var: floatfix(12345, 3);

is like $var: 12.345;

Maybe it’s of some use for someone.
Maybe less annoying than typing $var: 12345 / 1000;

Remember you can rename that function if "floatfix" seems too long for practical use.

@Darkwing371

Really? Am I the only one with this problem? Baffles me …

By the way, I wrote a more sophisticated version of floatfix:

 // new version of floatfix
 // maybe more intuitive to use: f(1,23) -> 1.23 (number)
 // takes two arguments and interprets them to build a floating point
 // cleverly using the arguments comma as decimal point

 @function f($integer: 0, $decimals: null) {

   $value: $integer; // default in any cases; cut decimals

   // but if both arguments are normal integer numbers,
   // then suitable for our little trick
   @if is-int($integer) and is-int($decimals) and ($decimals > 0) {

    $d: $decimals;    // for init
    $p: 1;            // counter for decimal places

    // find out how many decimal places are present
    // = "length of decimal number"
    // note: truncated by sass::number::precision anyway; 5 digits by default
    @while $d > 0 {

        $d: floor($d / 10 ); 
        $p: $p * 10;
    }

    // build our floating point decimal
    $value: $integer + ( $decimals / $p );
  }

   @return $value;
 }

Needs little function is-int()

 // simply detects, if given value is an integer
 @function is-int($value: false) {  

   @if type-of($value) == "number" {
     @return round($value) == $value;
     }
     @else { @return false; } 
   }
@elflo

Thank you for this, it has been driving me crazy as well! However, it seems to work fine when compiling using the command line. I'm on OSX, and i get accurate results when i compile using sass input.scss output.css in the terminal. Maybe this is a Scout-related issue rather than a problem with Sass itself?

@Darkwing371

Yes, I also think this must be Scouts problem. Maybe one day I try to make single installations of Ruby and Sass and Compass – advantage: one could always use the latest build/comit of Sass available on GitHub. (I saw a comit where string operations are made possible, like strlen() and so on; my boy, my boy! ;) )

Scout seems very very good for beginning, but obviously has some disadvantages/bugs.

@zdennis
Owner

I agree with everything @Darkwing371 said.

For the record, Scout has nothing to do with compiling, it merely starts a compass watch process. But maybe there's something in how Adobe AIR and/or the version of JRuby we're using impacts things. If so, it's very indirectly.

In terms of the disadvantages and bugs. Those should be worked out at some point, but obviously haven't been addressed in a long while.

@jswebschmiede

i have the same problem. also in the new version. when i use command line commmands everything fine.

@pedrotainha

I got the same problem also, at least i think, but in a strange way.
I got my mixins in a import scss file. When i save the file that calls the mixin and for example like this:
@include opacity(0.65);
Everything compiles well, but if i make changes in my import file, the scout or the compass, not sure witch of them, find all scss files that import this file with mixins.
The issue cames here because it compile my opacity mixins like if i had wrote @include opacity(0);
here is the mixin:
@mixin opacity($opac:1, $imp:''){
$opacie : $opac100;
/
IE 8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=#{$opacie}) #{$imp}";

/* IE 5-7 */
filter: alpha(opacity=#{$opacie} #{$imp});

/* Netscape */
-moz-opacity: #{$opac} #{$imp};

/* Safari 1.x */
-khtml-opacity: #{$opac} #{$imp};

/* Good browsers */
opacity: #{$opac} #{$imp};
}

@jswebschmiede

old Problem, no fix, :-1:

@JeffDess

I also experienced the same problem under Windows 7 Entreprise, I've tried changing my locale settings but nothing would work. Compiling with a fresh installed Scout would round all floats, including rgba or font-size values. Running compass watch or compile in Ruby command line works just fine though. I've even tried to overwrite Scout's bin files with the one which are working on Ruby, but still no luck. I guess it's unlikely to be Compass or Sass related.

@brunnopleffken

I experienced the same problem (Windows 8 Pro 64) with Scout and decimal numbers...
Several times, my rgba(0, 0, 0, 0.3) turns into rgba(0, 0, 0, 0), messing all my front-end...

It's not a SASS-related issue... It seems to be Scout only, and it's so annoying!!
Now i'm using Koala for SASS/compass... Everything is OK, now!!

@arnolali

I experienced the same problem (OS X Mavericks) with Scout and decimal numbers.

@vdeboer

This problem still doesn't seem to be addressed. This topic was a great help, thanks Darkwing371.

Our experience is that this problem occurs in all the files except the last one that is being saved. So if you edit a file with floating points and save it the result from Scout is fine. If you then save another file, the floating points from the first file that you didn't change are cast to integers.

I modified the workaround function from darkwing a little:

@function floatfix($number: 1, $dec: 0, $unit : '' ) {
$multiplier : 1;
@while $multiplier <= $dec { $multiplier : $multiplier * 10; }
$float : ((($number*$multiplier)+$dec)/$multiplier);
@if $unit != '' { $float : $float + $unit; }
@return $float;
}

so you can write:
$var : floatfix(12,345);
or
$var : floatfix(12,345,em);

@Quevin

Is this now resolved? Seems to be...

@draiz

Still not solved! I'm having exactly the same issue working on a french install of Scout with many imported files.

@pisciottaf10

Any news?

@hugobqd

allways the same problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.