[ Launch: bitwize ] 5506427 by enjalot
[ Launch: test ] 5506324 by enjalot
-
-
Save enjalot/5506427 to your computer and use it in GitHub Desktop.
bitwize
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
{"description":"bitwize","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12},"number.js":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/lEgFmGd.png"} |
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
/* | |
This shows the bitwise operaionts "right shift" and "left shift" | |
We can see how a decimal number is represented as binary. | |
Notice how a right bit shift moves the binary numbers over by one (binary) digit. | |
This is kind of like dividing the number by 2 each shift (and rounding down). | |
What would happen if you shifted a decimal number to the right? it would be like | |
dividing by 10 and rounding down. | |
A javascript integer is made up of 32 bits, left shifting can push our binary past 32 bits, | |
which causes unexpected results. | |
We can also see the hex representation, which is spaced like the binary into bytes | |
(8-bits == byte) | |
For a lot of useful algorithms we break up our data into bytes and do | |
bitwise operations on those chunks of bytes. So it can be useful to see how | |
we can turn a number into bits and bytes and back again. | |
*/ | |
var svg = d3.select("svg"); | |
var NUMBER = 17678; | |
var maxbits = 32; | |
var nbits = NUMBER.toString(2).length; | |
var ng = svg.append("g") | |
.attr("transform", "translate(" + [tributary.sw - 239,64] + ")") | |
var rshift = svg.append("g") | |
.attr("transform", "translate(" + [tributary.sw - 661,276] + ")") | |
.append("text").classed("rshift", true) | |
.text(" >> " + 0) | |
var ng2 = svg.append("g") | |
.attr("transform", "translate(" + [tributary.sw - 239,229] + ")") | |
var lshift = svg.append("g") | |
.attr("transform", "translate(" + [tributary.sw - 661,455] + ")") | |
.append("text").classed("lshift", true) | |
.text(" << " + 0) | |
var ng3 = svg.append("g") | |
.attr("transform", "translate(" + [tributary.sw - 239,410] + ")") | |
tributary.numberForms(ng, NUMBER, maxbits) | |
tributary.run = function(g,t) { | |
var shift = Math.floor(t * (nbits+1)); | |
tributary.numberForms(ng2, NUMBER >> shift, maxbits) | |
tributary.numberForms(ng3, NUMBER << shift, maxbits) | |
svg.select(".rshift").text(" >> " + shift) | |
svg.select(".lshift").text(" << " + shift) | |
} | |
tributary.loop_type = "pingpong"; |
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
var twoColor = d3.scale.ordinal() | |
.domain([0, 1]) | |
.range(["#6CB8DB", "#63DACB"]); | |
var byteColor = d3.scale.linear() | |
.domain([0, 255]) | |
.range(["#9B0000", "#FFFFFF"]); | |
tributary.numberForms = numberForms | |
function numberForms(group,n, maxbits) { | |
//if(!maxbits) maxbits = 128 | |
//@params | |
// group: d3 selection to update our text | |
//display a number "n" in integer, hex, binary | |
//assumes positive integers | |
//TODO: sort out janky selection stuff to make more reusable. | |
group.selectAll("g.num").remove() | |
g = group.selectAll("g.num").data([0]) | |
g.exit().remove() | |
var dy = 30; | |
genter = g.enter() | |
.append("g").classed("num", true) | |
genter.append("g").classed("int", true) | |
genter.append("g").classed("bin", true) | |
.attr("transform", "translate(" + [0, dy] + ")") | |
genter.append("g").classed("hex", true) | |
.attr("transform", "translate(" + [0,2.5*dy] + ")") | |
genter.append("g").classed("dec", true) | |
.attr("transform", "translate(" + [0,3.5*dy] + ")") | |
genter.append("g").classed("bytes", true) | |
.attr("transform", "translate(" + [0,3*dy - 10] + ")") | |
var inttext = g.select("g.int"); | |
inttext.append("text") | |
//.text("decimal").attr("x", 10) | |
inttext.append("text").classed("number", true) | |
.text(n) | |
binaryVis(g.select("g.bin"),n,maxbits); | |
hexVis(g.select("g.hex"), n, maxbits); | |
decVis(g.select("g.dec"), n, maxbits); | |
//byteVis(g.select("g.bytes"), n, maxbits); | |
} | |
function binaryVis(g,n,maxbits) { | |
binwidth = 8.7; | |
binspace = 1.2 | |
var binary = n.toString(2); | |
//we want to pad our | |
var bits = binary.length; | |
zeropadding = zeropad(binary.length, maxbits) | |
binary = zeropadding + binary; | |
//binary = splitNumber(binary, 8); | |
binary = splitNumber(binary, 1); | |
g.selectAll("rect.digit") | |
.data(binary) | |
.enter() | |
.append("rect").classed("digit", true) | |
.attr({ | |
x: function(d,i) { return -(i+1) * (binwidth+binspace) - 5 * Math.floor(i / 8) }, | |
y: 10, | |
width: binwidth, | |
height: 10 | |
}) | |
.style({ | |
fill: function(d,i) { return ["#BD5D5D", "#D6B4B4"][+d] } | |
}) | |
g.append("text") | |
.text("binary: " + bits + " bits used").attr("x", 10).attr("y", 10) | |
g.append("text").classed("number", true).attr("x", -5) | |
.selectAll("tspan.chunks") | |
.data(binary.reverse()).enter().append("tspan") | |
.text(function(d){ return " " + d }) | |
//.style("fill", function(d,i) { return coloring(i%8, binary.length); }) | |
.attr("dx", function(d,i) { return (i%8) ? 0 : 4}) | |
} | |
function hexVis(g,n,maxbits) { | |
var hex = n.toString(16); | |
hex = zeropad(hex.length, maxbits/4) + hex; | |
hex = splitNumber(hex, 2) | |
var bytes = hex.length | |
g.append("text") | |
.text("hex: " + bytes + " bytes used").attr("x", 10) | |
g.append("text").classed("number", true).attr("x", "-0.5em") | |
.selectAll("tspan.chunks") | |
.data(hex.reverse()).enter().append("tspan").classed("chunks", true) | |
.text(function(d){ return " " + d.toUpperCase() }) | |
.attr("dx", "0.6em") | |
.style("fill", function(d,i) { return coloring(i, hex.length); }) | |
} | |
function byteVis(g,n,maxbits) { | |
var hex = n.toString(16); | |
hex = zeropad(hex.length, maxbits/4) + hex; | |
hex = splitNumber(hex, 2) | |
var bytes = hex.length; | |
var bytewidth = 16; | |
var bytespace = 9; | |
g.selectAll("rect.byte") | |
.data(hex.reverse()) | |
.enter().append("rect").classed("byte", true) | |
.attr({ | |
x: function(d,i) { return -(bytewidth + bytespace) * (i+1) }, | |
y: 0, | |
width: bytewidth, | |
height: bytewidth, | |
fill: function(d,i) { return byteColor(parseInt(d,16)) } | |
}) | |
} | |
function decVis(g,n,maxbits) { | |
var hex = n.toString(16); | |
hex = zeropad(hex.length, maxbits/4) + hex; | |
hex = splitNumber(hex, 2) | |
var bytes = hex.length | |
dec = []; | |
hex.forEach(function(h) { | |
var int = parseInt(h,16) + ""; | |
int = zeropad(int.length, 3) + int | |
dec.push(int) | |
}) | |
g.append("text") | |
.text("decimal: " + bytes + " bytes used").attr("x", 10) | |
g.append("text").classed("number", true) | |
.selectAll("tspan.chunks") | |
.data(dec.reverse()).enter().append("tspan").classed("chunks", true) | |
.text(function(d){ return " " + d }) | |
.style("fill", function(d,i) { return coloring(i, hex.length); }) | |
} | |
function zeropad(l, p) { | |
//given a number of l digits, give a string of 0s to pad with | |
//so that there is always a multiple of p digits | |
n = l % p; | |
if(n) | |
return d3.range(p - n).map(function() { return "0" }).join("") | |
return ""; | |
} | |
function splitNumber(s, l) { | |
//given a number (represented as a string "s") | |
//split it into chunks of size l | |
var chunks = []; | |
var chunk = ""; | |
for(var i = s.length; i--;) { | |
chunk = s[i] + chunk; | |
if(i % l === 0) { | |
chunks.push(chunk); | |
chunk = ""; | |
} | |
} | |
return chunks | |
} | |
function coloring(i,n) { | |
var ind = (n-i) & 1; | |
return twoColor(ind); | |
} |
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
#display { | |
background: #0A0C35; | |
} | |
g.num { | |
fill: #008A69 | |
} | |
.num .int .number { | |
font-family: "Courier New"; | |
text-anchor: end; | |
font-size: 28px; | |
fill: #00DA57 | |
} | |
.num .hex .number { | |
font-family: "Courier New"; | |
text-anchor: end; | |
font-size: 17px | |
} | |
.num .dec .number { | |
font-family: "Courier New"; | |
text-anchor: end; | |
font-size: 17px | |
} | |
.num .bin .number { | |
fill: #54E6D4; | |
text-anchor: end; | |
font-size: 12px | |
} | |
.rshift,.lshift { | |
fill: #D86F6F; | |
font-size: 31px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment