Last active
August 29, 2015 14:02
-
-
Save pascalduez/d1aac41e3ca449dd5518 to your computer and use it in GitHub Desktop.
Gray code (reflected binary code) convertion in Sass.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ---- | |
// Sass (v3.3.8) | |
// Compass (v1.0.0.alpha.19) | |
// SassyBitwise (v1.1.1) | |
// ---- | |
@import "SassyBitwise"; | |
// Gray code (reflected binary code) convertion in Sass. | |
// ----------------------------------------------------- | |
// JavaScript `toString` and `parseInt` implementation in Sass. | |
// https://gist.github.com/pascalduez/356aa6366ef0f077359f | |
// ------------------------------------------------------------ | |
@function pow($num, $exp) { | |
$result: 1; | |
@if $exp > 0 { | |
@for $i from 1 through $exp { | |
$result: $result * $num; | |
} | |
} | |
@else { | |
@for $i from $exp to 0 { | |
$result: $result / $num; | |
} | |
} | |
@return $result; | |
} | |
@function charsFromBase($base: 10) { | |
$chars:( | |
// Binary | |
2: '01', | |
// Octal | |
8: '01234567', | |
// Decimal | |
10: '0123456789', | |
// Hexadecimal | |
16: '0123456789abcdef', | |
// Base 36 | |
36: '0123456789abcdefghijklmnopqrstuvwxyz', | |
// Base 64 | |
64: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/=' | |
); | |
@if not map-has-key($chars, $base) { | |
@warn "There is no base `#{$base}` available."; | |
} | |
@return map-get($chars, $base); | |
} | |
@function toString($num, $radix: 10) { | |
$chars: charsFromBase($radix); | |
$result: ''; | |
$sign: ''; | |
@if $num < 0 { | |
$sign: '-'; | |
$num: abs($num); | |
} | |
@if $num >= 0 and $num < $radix { | |
@return $sign + str-slice($chars, ($num + 1), ($num + 1)); | |
} | |
$q: $num; | |
@while $q != 0 { | |
$r: $q % $radix; | |
$q: floor($q / $radix); | |
$result: str-slice($chars, ($r + 1), ($r + 1)) + $result; | |
} | |
@return $sign + $result; | |
} | |
@function parseInt($str, $radix: 10) { | |
$chars: charsFromBase($radix); | |
$result: 0; | |
$is-negative: str-index($str, '-') == 1; | |
@if $is-negative { | |
$str: str-slice($str, 2); | |
} | |
@for $i from 1 through str-length($str) { | |
$char: str-slice($str, -$i, -$i); | |
$value: str-index($chars, $char) - 1; | |
$result: $result + ($value * pow($radix, ($i - 1))); | |
} | |
@return if($is-negative, -$result, $result); | |
} | |
// Gray code | |
// https://en.wikipedia.org/wiki/Gray_code | |
// --------------------------------------- | |
// Helpers | |
// Convert a 1 bit string to its number equivalent. | |
@function bit($str) { | |
@return (str-index('01', str-slice($str, -1)) - 1); | |
} | |
// Padd a binary string with zeros. | |
@function padd($bin, $length: 4) { | |
@if not index(2 4 8 16 32 64, $length) { | |
@return $bin; | |
} | |
@while str-length($bin) < $length { | |
$bin: '0' + $bin; | |
} | |
@return $bin; | |
} | |
// Convert an unsigned binary string (natural binary code) | |
// to a Gray code string (reflected binary code). | |
@function binaryToGray($str) { | |
$num: parseInt($str, 2); | |
$num: bw(bw($num '>>' 1) '^' $num); | |
@return toString($num, 2); | |
}; | |
// Convert a Gray code string (reflected binary code) | |
// to an unsigned binary string (natural binary code). | |
@function grayToBinary($str) { | |
$gray: (); | |
$bin: (); | |
$result: ''; | |
@for $i from 1 through str-length($str) { | |
$gray: append($gray, bit(str-slice($str, $i, $i))); | |
} | |
$bin: append($bin, nth($gray, 1)); | |
@for $i from 2 through length($gray) { | |
$bin: append($bin, bw(nth($gray, $i) '^' nth($bin, $i - 1))); | |
} | |
// Concatenate into a string. | |
@each $bit in $bin { | |
$result: $result + $bit; | |
} | |
@return $result; | |
}; | |
tests { | |
$fixture: ( | |
0: ( "bin": "0000", "gray": "0000" ), | |
1: ( "bin": "0001", "gray": "0001" ), | |
2: ( "bin": "0010", "gray": "0011" ), | |
3: ( "bin": "0011", "gray": "0010" ), | |
4: ( "bin": "0100", "gray": "0110" ), | |
5: ( "bin": "0101", "gray": "0111" ), | |
6: ( "bin": "0110", "gray": "0101" ), | |
7: ( "bin": "0111", "gray": "0100" ), | |
8: ( "bin": "1000", "gray": "1100" ), | |
9: ( "bin": "1001", "gray": "1101" ), | |
10: ( "bin": "1010", "gray": "1111" ), | |
11: ( "bin": "1011", "gray": "1110" ), | |
12: ( "bin": "1100", "gray": "1010" ), | |
13: ( "bin": "1101", "gray": "1011" ), | |
14: ( "bin": "1110", "gray": "1001" ), | |
15: ( "bin": "1111", "gray": "1000" ) | |
); | |
$test: ''; | |
@each $num, $data in $fixture { | |
$pass: padd(binaryToGray(map-get($data, "bin"))) == map-get($data, "gray"); | |
$test: $test + if($pass, '✔ ', 'X '); | |
} | |
/* binaryToGray */ | |
test: $test; | |
$test: ''; | |
@each $num, $data in $fixture { | |
$pass: grayToBinary(map-get($data, "gray")) == map-get($data, "bin"); | |
$test: $test + if($pass, '✔ ', 'X '); | |
} | |
/* grayToBinary */ | |
test: $test; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@charset "UTF-8"; | |
tests { | |
/* binaryToGray */ | |
test: "✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ "; | |
/* grayToBinary */ | |
test: "✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔ "; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment