Skip to content

Instantly share code, notes, and snippets.

@ityonemo
Created August 14, 2015 01:41
Show Gist options
  • Select an option

  • Save ityonemo/08b98850a8e459c09d2c to your computer and use it in GitHub Desktop.

Select an option

Save ityonemo/08b98850a8e459c09d2c to your computer and use it in GitHub Desktop.
testing things from end of error
#test-things-from-the-book.jl
include("unum.jl")
using Unums
using Base.Test
#test various things from the book.
#are our representations of unums correct?
one16 = one(Uint16)
one64 = one(Uint64)
zero16 = zero(Uint16)
zero64 = zero(Uint64)
top64 = 0x8000_0000_0000_0000 #our representation for the fraction part is left-shifted.
#p.27, representation of simple unums. In the tiny environment{1, 0}
#John Gustafsson's formula for unum calculation is as follows:
#(note that in our internal Unum structure, esize = es - 1)
#this differs from our internal unum calculation
function bookcalculate(x::Unum)
#the sub`normal case
if (x.exponent == 0)
2.0^(x.exponent - 2.0^(x.esize)) * (big(x.fraction) / 2.0^64)
else #the normalcase
2.0^(x.exponent - 2.0^(x.esize) - 1) * (1 + big(x.fraction) / 2.0^64)
end
end
#FOR REFERENCE, the code internal to the standard unum looks as follows:
# 2.0^(x.exponent - 2.0^(x.esize) + 1) * (big(x.fraction) / 2.0^64)
# 2.0^(x.exponent - 2.0^(x.esize)) * (1 + big(x.fraction) / 2.0^64)
#note that this actually matches the description of subnormals in the book
#
# "If all exponent bits are 0 , then add one to the exponent and use 0 for the hidden bit."
#claim: 0 00 1 0 +(utag) should be 1/2
uhalf = Unum{1,0}(zero16, one16, zero16, top64, zero64)
@test "0 00 1 0" == bits(uhalf, " ")[1:8] #note throw away the utag, as in the book.
#oops! Neither formula yields the correct result.
@test 0.5 != Unums.calculate(uhalf)
@test 0.5 != bookcalculate(uhalf)
#let's try the better Unum representation 0 0 1 0 (0 0)
uhalf = Unum{1,0}(zero16, zero16, zero16, top64, zero64)
@test "0 0 1 0 0 " == bits(uhalf, " ") #note the trailing space due to the zero-bit float
@test 0.5 == Unums.calculate(uhalf)
#claim: 0 01 0 0 +(utag) should be one
uone = Unum{1,0}(zero16, one16, zero16, zero64, one64)
@test "0 01 0 0" == bits(uone, " ")[1:8] #note: throw away the utag, as in the book.
@test 1.0 != Unums.calculate(uone)
@test 1.0 != bookcalculate(uone)
#try the better Unum representation 0 1 0 0 (0 0)
uone = Unum{1,0}(zero16, zero16, zero16, zero64, one64)
@test "0 1 0 0 0 " == bits(uone, " ") #note the trailing space due to the zero-bit fraction
@test 1.0 == Unums.calculate(uone)
#fixing the warlpiri numbers
#the claim is that in warlpiri numbers:
#0010 == 1
#0100 == 2
#let's construct them.
warlone = Unum{0,0}(zero16, zero16, zero16, top64, zero64)
@test "0010" == bits(warlone)
#unfortunately this doesn't jive with the gustafson formula
@test 1.0 != bookcalculate(warlone)
#turns out it's even worse than our formula, which says that it should be a half
@test 0.5 == Unums.calculate(warlone)
@test 0.25 == bookcalculate(warlone)
warltwo = Unum{0,0}(zero16, zero16, zero16, zero64, one64)
@test "0100" == bits(warltwo)
#again, this doesn't jive with the gustafson formula
@test 2.0 != bookcalculate(warltwo)
#whereas our formula says it should be "one", which is consistent with above!
@test 1.0 == Unums.calculate(warltwo)
@test 0.5 == bookcalculate(warltwo)
#all tests pass
#note that even upshifting the exponent representation doesn't fix the
#bookcalculate values. That's ok, though, warlpiri numbers that are {-1, -1/2, 1/2, 1} are just as
#interesting to me.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment