ValueErrorException: math domain error

Could anyone share a trick to avoid errors caused by python internal rounding?

import rhinoscriptsyntax as rs
import math
listX = []
for i in range(n):
    listX.append(((p2.X - p1.X)/(n-1))*i)
print(listX)

r = p2.X - p1.X
print(r)

pts = []
for k in range(n):
    pts.append(rs.AddPoint(round(listX[k],3),-round((math.sqrt(r**2 - (listX[k]-p1.X)**2)-p2.Y),3)))

GH.ArrangePointsInQuarterCircle.gh (6.5 KB)

It may be the sqrt call. I would suggest breaking line 39 into several lines of code. There is too much packed into that single line to determine where the real problem lies.

Thanks Steve,

Still though even if I “unpack” that line into

pts = []
for k in range(n):
    tmpX=round(listX[k],3)
    tmpY=-round((math.sqrt(r**2 - (listX[k]-p1.X)**2)-p2.Y),3)
    tmpPt = rs.AddPoint(tmpX,tmpY)
    pts.append(tmpPt)

I think it’s because of that 200.00000000000003 value

That should be 200.0.
It only happens when I set the n input to 12.

You still didn’t unpack it enough to be able to determine if the problem is round or sqrt

it’s not the round because I put it there to try to avoid the issue.

but round is outside the sqrt call so it wouldn’t have any effect. Can you tell if a negative number is getting passed to sqrt?

this is sqrt(200^2 - (200.00000000000003 - 200)^2)

sqrt(400-0.0000000000000000000000000009)

This is the list:
[0.0, 18.181818181818183, 36.363636363636367, 54.545454545454547, 72.727272727272734, 90.909090909090921, 109.09090909090909, 127.27272727272728, 145.45454545454547, 163.63636363636365, 181.81818181818184, 200.00000000000003]

The problem appears at the last point.

if you uncomment this you’ll see it’s the last one:
image

What is the value of p2.Y? It looks like that is also part of the equation

200.0

I have attached the GH file in the original post.

You can use the decimal module in Python if you need to do precise decimal arithmetic. At some point you need to turn the answer into a float to use it with rhino.

I don’t need it precise I need it to not create that small values, I think decimal will be even worse, even smaller value.

I was thinking about rounding values, then converting into string and back to float.

These are the values of n where the issue appears in range(3-100):
12
23
40
45
79
84
89
92

That worked:

listX = []
for i in range(n):
    v1 = ((p2.X - p1.X)/(n-1))*i
    v2 = round(v1,3)
    v3 = str(v2)
    v4 = float(v3)
    listX.append(v4)

Which means there’s a serious issue either with coordinates coming from Rhino or with Python’s calculations.

1 Like

It’s a problem with floating point arithmetic generally, not just Rhino or Python.
In Python:

math.sqrt(200)**2

Gives 200.00000000000003

You’re right that the decimal module doesn’t solve this as root 200 is irrational so has no precise decimal value:

From decimal import Decimal
Decimal(200).sqrt()**2

Gives Decimal(‘199.9999999999999999999999999’) with my default precision settings

1 Like

You could also use sqrt(max(0, expression)) to avoid taking the square root of a negative number.

1 Like