Community Tip - You can subscribe to a forum, label or individual post and receive email notifications when someone posts a new topic or reply. Learn more! X
Hi
We have a crazy relation in our start part that converts the system generated PRO_MP_MASS in a Text Parameter with 3 decimal places, which can then be used to set the weight property within our PLM system, Teamcenter. Im not a fan of this relation as its about 27 lines long. I once found a new relation, shown below, on a website, but cant for the life of me remember where. Trouble is, when Ive come to try it out, its not giving the correct answer, compared to the generated mass property. Dec_P is set as a parameter to 3
RN = FLOOR((PRO_MP_MASS+(5/10^(DEC_P+1))),DEC_P)
IF FLOOR(RN) == 0
MASS = "0."+ITOS((RN-FLOOR(RN))*10^(DEC_P))
ELSE
MASS = ITOS(FLOOR(RN))+"."+ITOS((RN-FLOOR(RN))*10^(DEC_P))
ENDIF
Solved! Go to Solution.
This one from Ken seems to work well
RN = FLOOR((PRO_MP_MASS+(5/10^(DEC_P+1))),DEC_P)
IF RN < 1.0
MASS = "0."
ELSE
MASS = ITOS ( FLOOR ( RN ) ) + "."
ENDIF
MASS = MASS + EXTRACT ( ITOS ( 10^DEC_P * ( 1 + RN - FLOOR ( RN ) ) ), 2, 3 )
Stu
"Sunday bloody Sunday" 🙂
This is working for negative numbers and denominators (-,0,+) as well. Dependent on your needs, it can be simplified.
dval=1.399e-06
nd=7
Output would be -> 0.0000014
dval=-116.654
nd=0
/* Debug Variable
dlen=-1
/* get the postive rounded value
rval=floor(abs(dval)*pow(10,nd)+0.5)/pow(10,nd)
/* multiply by 10 power of the abs value
sval = itos(rval*pow(10,abs(nd)))
/* first string len
slen =floor(string_length(sval))
if (dval < 1)
/* only for Debug
dlen=slen
/* Check if we need to prepend set new sval
sval= extract("0000000000",1,abs(nd) +1 -slen ) + sval
/* set new slen
slen =string_length(sval)
endif
/* only if you are okay with a dot at the end and no trailing number
if (nd > 0)
sdval=extract(sval,1,slen-nd) + '.' + extract(sval,slen-abs(nd)+1,nd*nd/nd)
else
sdval=extract(sval,1,slen-abs(nd))
endif
/* Final change for negative numbers
if (dval<0)
sdval='-'+ sdval
endif
Hi @stu-aspinall,
Can you elaborate on how the relation is not giving the correct answer? Is it off by a factor, rounding error, etc.? Any errors in the relation?
I used your relation and DEC_P = 3 with a 1x1x1 inch legacy steel cube and the result was 0.283 and a 10x10x10 with result 282.771 which match the calculated mass properties.
Thanks,
Michael
Hi Mike
I have one with a bar, dia 20mm x 100mm, with a density of 1.399e-06 kg/mm3, where the mass prop analysis gives 4.398e-02 Kg. Mass gives as 0.44, whereas RN reports back as 0.044
Stu
Hi @stu-aspinall,
Using the Evaluate Expression tool [=?] in the relations to break the MASS= line into smaller portions of math
(RN-FLOOR(RN)) = 0.044
10^(DEC_P) = 1000
0.044*1000 =44
"0." + "44" = "0.44"
It looks like the relations are not accounting for the leading zeros between RN and 10^DEC_P. This makes me wonder what the original 27 line relation was doing and if those additional lines were considering this.
As @BenLoosli calls out, Creo 11.0's RTOS command looks like it will be a game-changer for both these relation sets.
https://support.ptc.com/help/creo/creo_pma/r11.0/usascii/index.html#page/whats_new_pma/fund_real_to_string.html
Thanks Mike
This was the ridiculous relation someone put into our start part, which I want to suggest changing.
height=PRO_MP_MASS
h=floor(height)
IF h == 0
h_s = "0"
ELSE
h_s=itos(h)
ENDIF
h1=floor(height*10)-(h*10)
IF h1 == 0
h1_s = "0"
ELSE
h1_s=itos(h1)
ENDIF
h2=floor(height*100)-(h*100)-(h1*10)
IF h2 == 0
h2_s = "0"
ELSE
h2_s=itos(h2)
ENDIF
h3=floor(height*1000)-(h*1000)-(h1*100)-(h2*10)
IF h3 == 0
h3_s = "0"
ELSE
h3_s=itos(h3)
ENDIF
weight= h_s+"."+h1_s+h2_s+h3_s
MASS=WEIGHT
Stu
This one from Ken seems to work well
RN = FLOOR((PRO_MP_MASS+(5/10^(DEC_P+1))),DEC_P)
IF RN < 1.0
MASS = "0."
ELSE
MASS = ITOS ( FLOOR ( RN ) ) + "."
ENDIF
MASS = MASS + EXTRACT ( ITOS ( 10^DEC_P * ( 1 + RN - FLOOR ( RN ) ) ), 2, 3 )
Stu
Yes this is the mistake, leading zero will lead to wrong results 😅.
12.4532 will work
12.003 will fail you will get 12.300
You need to have an addition function. Based of the result you may need to prepend zeros, for 3 digits and itos len is 1 you need to prepend „00“ (3-1) from a dummy string like „000000“
Not having a format function, lead to much greater relations and regeneration time 😉
I also does not understand this part
PRO_MP_MASS+(5/10^(DEC_P+1))
this
5/10^(DEC_P+1) will just produce 0.5, 0,05, 0,005 …
instead of this, just divide 0.5 by 10^DEC_P
-> PRO_MP_MASS+(.5^DEC_P)
less parse and calculation time😉
Note: DEC_P can also be negative and produce valid results. But for this you must change the calculation. This one poorly deals with the decimal ending, not with the the whole number
116 can be converted to 120 for negative ones.
And 0 as well to produce a rounded integer😅
Perhaps something like this for 3 decimal places:
mass = floor(PRO_MP_MASS*1000+0.5)/1000
Edit: Sorry, I misunderstood the question.
Please explain why it isn't working.
It worked fine when I copied it into a test file.
pro_mp_mass = 9.914639
RN = 9.915 (real number)
Mass = 9.915 (string)
Hi
I have one with a bar, dia 20mm x 100mm, with a density of 1.399e-06 kg/mm3, where the mass prop analysis gives 4.398e-02 Kg. Mass gives as 0.44, whereas RN reports back as 0.044
Stu
The ITOS function returns "" or an empty string, when the value presented to it is zero. It does not give you leading zeros. Two cases where what you are looking for will not be provided. My method for this is, using your variables:
IF RN < 1.0
MASS = "0."
ELSE
MASS = ITOS ( FLOOR ( RN ) ) + "."
ENDIF
MASS = MASS + EXTRACT ( ITOS ( 10^DEC_P * ( 1 + RN - FLOOR ( RN ) ) ), 2, 3 )
What I'm doing is building the part of the number that is before the decimal place, then using a bit of digit shifting to extract the desired number of places after the decimal.
Hi Ken
I have one with a bar, dia 20mm x 100mm, with a density of 1.399e-06 kg/mm3, where the mass prop analysis gives 4.398e-02 Kg. Mass gives as 0.44, whereas RN reports back as 0.044000
Adding your extra bit to the end of the original relation, makes the two parameters match.
I'll do a few more tests today/tomorrow.
Thanks
Stu
Morning Ken
So the relation should look like this
RN = FLOOR((PRO_MP_MASS+(5/10^(DEC_P+1))),DEC_P)
IF RN < 1.0
MASS = "0."
ELSE
MASS = ITOS ( FLOOR ( RN ) ) + "."
ENDIF
MASS = MASS + EXTRACT ( ITOS ( 10^DEC_P * ( 1 + RN - FLOOR ( RN ) ) ), 2, 3 )
Stu
Sure, that's pretty much what I wrote. Hopefully I didn't miss a comma or something. Why don't you just try it and see if it works?
When I'm trying out this kind of thing I test out the technique on one value, see how things go, and correct my errors, before changing anything important. Often I'll just use (temporary) test parameters that I can set and check.
With Creo 11, this will be easier as PTC has finally added a RtoS (Real to String) function in relations.
mass = rtos(pro_mp_mass,3) will give 3 decimal places to the string parameter named mass.
Unfortunately Ben, our IT have a rule of thumb of latest version minus 1, so with us currently on 7 (guess they need new batteries in their calculator) we wont get to Creo 11 until probably 2030...lol
Stu
That is a long relation for what can be easier to calculate.
I hear you on being behind a bit. I am not as bad as your IT, I usually start doing installs at the 5th release, so Creo 11.0.5.0 or Windchill 13.0.2.5. Let someone else bleed from the cutting edge!
And this can’t be fixed with OOTB functionality using [.≠] where ≠ is the number of decimal places?
In C format .2f on a double value. This was working in ProE as well if I remember correctly 😉
CS56347
…
This syntax can be used in modeling mode as well to alter notes or standard hole notes
This syntax can also be used in repeat region tables (for example, &mbr.param.value[.0])