Skip to content

Instantly share code, notes, and snippets.

@pascalduez
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pascalduez/d1aac41e3ca449dd5518 to your computer and use it in GitHub Desktop.
Save pascalduez/d1aac41e3ca449dd5518 to your computer and use it in GitHub Desktop.
Gray code (reflected binary code) convertion in Sass.
// ----
// 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;
}
@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