Created
April 3, 2014 12:36
-
-
Save dwilliamson/9953484 to your computer and use it in GitHub Desktop.
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
# | |
# Correcting Art of Assembly's flawed acos implementation in Chapter 14 | |
# http://flint.cs.yale.edu/cs422/doc/art-of-asm/pdf/CH14.PDF | |
# | |
import math | |
# Alias commonly used math functions | |
sqrt = math.sqrt | |
atan = math.atan | |
atan2 = math.atan2 | |
# | |
# From Art of Assembly, Chapter 14 | |
# States allowable range is -1 <= x <= 1 | |
# Does not work for x < 0 | |
# | |
def acos_ArtOfASM(x): | |
return atan(sqrt((1 - x * x) / (x * x))) | |
# | |
# From Mathworld, correctly states range is x >= 0 (with x=0 caveat) | |
# http://mathworld.wolfram.com/InverseCosine.html | |
# | |
def acos_Mathworld(x): | |
return atan(sqrt((1 - x * x) / x)) | |
# | |
# Use atan2 to cater for x <= 0 by taking quadrant shift into account: | |
# | |
# atan2(y, x) = ... | |
# atan(y / x) x > 0 | |
# atan(y / x) + pi y >= 0, x < 0 | |
# atan(y / x) - pi y < 0, x < 0 | |
# pi / 2 y > 0, x = 0 | |
# -pi / 2 y < 0, x = 0 | |
# | |
def acos_MathworldQuadrant(x): | |
return atan2(sqrt(1 - x * x), x) | |
print acos_ArtOfASM(1) | |
print acos_ArtOfASM(-1) | |
print acos_Mathworld(1) | |
print acos_Mathworld(-1) | |
print acos_MathworldQuadrant(1) | |
print acos_MathworldQuadrant(-1) | |
# | |
# This results in a more correct implementation with the input range -1 <= x <= 1 | |
# 1 less instruction and fdiv swapped for a fxch instruction | |
# | |
__asm | |
{ | |
fld st(0) // [x] | |
fld st(0) // [x] [x] | |
fmul // [x * x] [x] | |
fld1 // [1] [x * x] [x] | |
fsubr // [1 - x * x] [x] | |
fsqrt // [sqrt(1 - x * x)] [x] | |
fxch st(1) // [x] [sqrt(1 - x * x)] | |
fpatan // [acos] | |
ret | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment