If you look at the amount of digits that are displayed this should help to identify the issue.
What seems to be happening is that it is limiting the displayed total numbers to 15(16 characters if you include the dot). This means the one with “10” at the start has 2 digits prior to the dot and 13 digits afterwards. Once you add 100 to it this means there is now 3 digits prior to the dot so therefore can only display 12 digits afterwards.
I haven’t seen your python code so i cannot comment about it, but have you tried just adding .ToString() to the end of where the number is set to see what the outcome is?
Eg:
Number.ToString()
I am unsure if the additional areas of what you have indicated can be added within the () for the tostring method, but you could try and see?
I’m trying to calculate how much times a dimension is dividable by (value 1 + value 2). if it automaticly rounds the outcome of (value 1 + value 2) for me, i get wrong outcomes.
you are running into the limits of double precision floating pt numbers:
The 53-bit significand precision gives from 15 to 17 significant decimal digits precision (2−53 ≈ 1.11 × 10−16). If a decimal string with at most 15 significant digits is converted to IEEE 754 double-precision representation, and then converted back to a decimal string with the same number of digits, the final result should match the original string. If an IEEE 754 double-precision number is converted to a decimal string with at least 17 significant digits, and then converted back to double-precision representation, the final result must match the original number.[1]
if you need more precision you will have to look into arbitrary precision numbers and math libraries.
userinput: seam value = 700/65 in this case the 10.(alot decimals)
userinput: brick value = 100
in python brick = seam + brick 110. (alot decimals, in this case)
and because of the rounding somewhere in python it always gives me the else case instead of elif.
@Mostafa_El_Ayoubi we currently use the Data Shapes package to input number value’s (which always works if they are readable numbers)
would it be possible to let the user give the division? 700/65 is alot easyer than 10.7692307692308
@kulkul i think the link in my last post was the best description. Also the script works, it Just seems not precise enough in case the user inputs alot decimals. In the example in the picture below it works (its calculating the dimension.below value based on dimension value)
if it automaticly rounds the outcome of (value 1 + value 2) for me, i get wrong outcomes.
Excuse me if i’m being stupid, but your number is going off to infinity…
So there has to be rounding?
I’m probably misunderstanding… But I tried to suggest (badly) in the previous thread, that it’s surprisingly hard to establish from the calculating values whether a calculated number will be correct to a specific decimal place.
My experience with your method is that it works for 99% of cases. I showed a graph which instead works off the calculated values, finds the surrounding correct numbers and compares them.
The next piece of code by @kennyb6 works on whole numbers, i’m trying to adapt it to make it work with decimal numbers to. Python Dimension.Below = calculated value based on actual Dimension value(Maths)
at first i thought it wasnt possible, but now i got a ‘breakthrough’
the piece of code that i have works on a single string. and i want to adapt it to work with multiple dim values like the piece of code @kennyb6 wrote.
see attachments and code below.
Actual code that works:
# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
# Functions
def getForm(dim, brick, brickN, seam, seamN):
val = round(dim.Value * ftmm)
x = str(int(round(val / brick)))
if val % brick == seam:
form = x + brickN + " + " + seamN
elif val % brick == brick - seam:
form = x + brickN + " - " + seamN
elif val % brick == 0:
form = x + brickN
else:
form = str(int(val // brick)) + brickN + " + R"
dim.Below = form
return form
# The inputs to this node will be stored as a list in the IN variables.
allDims = UnwrapElement(IN[0])
brick = IN[1]
seam = IN[2]
brickN = IN[3]
seamN = IN[4]
ftmm = 304.8
forms = []
TransactionManager.Instance.EnsureInTransaction(doc)
for dims in allDims:
if dims.Value == None:
form = []
for dim in dims.Segments:
form.append(getForm(dim, brick, brickN, seam, seamN))
forms.append(form)
else:
form = []
form.append(getForm(dims, brick, brickN, seam, seamN))
forms.append(form)
TransactionManager.Instance.TransactionTaskDone()
OUT = forms
The piece of code that i m trying to adapt:
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import sys
sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import decimal
from decimal import *
getcontext().rounding = ROUND_HALF_UP
getcontext().prec = 12
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
bS = IN[0]
brick = IN[1]
tolerance = IN[2]
dimValue = IN[3]
D = decimal.Decimal
seam = str(D(bS) - D(brick))
bsLow = str(D(bS) - D(tolerance))
bsHigh = str(D(bS) + D(tolerance))
brickLow = str(D(brick) - D(tolerance))
brickHigh = str(D(brick) + D(tolerance))
seamLow = str(D(seam) - D(tolerance))
seamHigh = str(D(seam) + D(tolerance))
toleranceLow = str( 0 - D(tolerance))
toleranceHigh = str(D(tolerance))
strVoeg = ''
km_in_maat = str(int(D(dimValue) / D(bS))) # aantal bS
rest = str(D(dimValue) % D(bS))
if D(bsLow) <= D(rest) <= D(bsHigh):
km_in_maat = str(D(km_in_maat) + 1)
strVoeg = km_in_maat + 'K'
elif D(brickLow) <= D(rest) <= D(brickHigh):
km_in_maat = str(D(km_in_maat) + 1)
strVoeg = km_in_maat + 'K-V'
elif D(seamLow) <= D(rest) <= D(seamHigh):
if km_in_maat == '0':
strVoeg = 'R' # 0K+V >>> R
else:
strVoeg = km_in_maat + 'K+V'
else:
if km_in_maat == '0':
strVoeg = 'R'
elif D(toleranceLow) <= D(rest) <= D(toleranceHigh):
strVoeg = km_in_maat + 'K'
else:
strVoeg = km_in_maat + 'K+R'
OUT = strVoeg
Currently i m feeding it a single string. it needs some changes to work with dim values i think, i just dont know what to change. any help is greatly appreciated!