iuhytvYUTCU
Member
OP
Yes you are right about that, sorry I am not native English speaker.That would perhaps be better stated as "limitations regarding precision."
-
Yes you are right about that, sorry I am not native English speaker.That would perhaps be better stated as "limitations regarding precision."
-
It isn't a matter of which method is the most popular. The art of engineering lies in the application of the best tool to the task at hand. The "Equal" and "Range" instructions are both viable tools. "Equal" is better suited to integer comparisons than to floating point comparisons. If speed is a factor, integer instructions have faster execution times than floating point. You need to consider all of the pertinent parameters for your application. Pursuit of greater precision quickly reaches a point of diminishing return for the effort expended. There is no exact value for PI.Ok so the solution points to using integer actually, I think integer will receive most of the votes now
>>> import numpy
>>> import struct
>>> ratio = numpy.float32(16777215) / numpy.float32(16777216)
>>> one = numpy.float32(1)
>>> hex(struct.unpack('I',struct.pack('f',one))[0])
'0x3f800000'
>>> hex(struct.unpack('I',struct.pack('f',ratio))[0]) <== Mantissa decreased by one bit
'0x3f7fffff'
>>> hex(struct.unpack('I',struct.pack('f', ratio*ratio ))[0]) <== Mantissa decreased by another bit
'0x3f7ffffe'
>>> hex(struct.unpack('I',struct.pack('f',one/ratio))[0]) <== Mantissa increased by one bit
'0x3f800001'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.015)))[0])
'0x3c75c28f'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.016)-numpy.float32(0.001)))[0])
'0x3c75c290'
>>> hex(struct.unpack('I',struct.pack('f', (numpy.float32(0.016)-numpy.float32(0.001)) * ratio ))[0]) <== Multiplying by ratio decreases mantissa by one bit; lower limit is now <= 0.015
'0x3c75c28f'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.017)))[0])
'0x3c8b4396'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.016)+numpy.float32(0.001)))[0])
'0x3c8b4396'
>>> hex(struct.unpack('I',struct.pack('f', (numpy.float32(0.016)+numpy.float32(0.001)) / ratio ))[0]) <== Dividing by ratio increases mantissa by one bit; upper limit is now >= 0.017
'0x3c8b4397'
If speed is a factor, integer instructions have faster execution times than floating point.
Yes you are right about that, sorry I am not native English speaker.
Please do not apologize for that; your English is far better than my 中文!
is it true that 0.001 is the resolution of all numbers and multiplying by 1000 will do the magic?
The PLC make and model are as yet unknown
-
I undertand, however I am just trying to compare two numbers in the first place, rather than doing more math in depth, I just care about the relation of the value of them, so the simplest way to compare REALs while not maintaining/converting they is okayYes, but the real issue then becomes the conversion of the scaled values from floating-point to integer, specifically whether it is done via truncation or rounding.
It is nice that you happen to know some of Chinese, hahaPlease do not apologize for that; your English is far better than my 中文!
I apologize if I offended; I was only trying to emphasize the distinction between precision and accuracy. Also, now that I think about it, while it is the precision limits of floating point that give rise to the problem, it is ultimately the accuracy of floating point that is the problem itself, so perhaps you were correct to use accuracy in the first place.
-
Looks like I will take some time to digest your post...Using the calculated lower_limit and upper_limit will solve this difference-of-difference "non-"issue.
- Calculate ratio = 16777215.0 / 16777216.0
- Multiply the [lower limit calculated by difference] by ratio to get the actual lower limit i.e. lower_limit = (0.016 - 0.001) * ratio
- Divide the [upper limit calculated by sum] by ratio to get the actual lower limit i.e. upper_limit = (0.016 + 0.001) ÷ ratio
TL;DRThe PLC make and model are as yet unknown, but the following example in python should emulate the suggested solution.P.S. This is more or less the same as converting to INT or DINT milli-units, as suggested by others; either way will work. This way will take less code and allows using the floating point value to be used as-is when it is compared to the massaged limits. That said, since this all encapsulated in an AOI those are not reasons to choose this path over the 1k/INT/DINT route, a better metric for choosing one over the other is whether the coders and maintainers understand it.
>>> import numpy
>>> import struct
>>> ratio = numpy.float32(16777215) / numpy.float32(16777216)
>>> one = numpy.float32(1)
>>> hex(struct.unpack('I',struct.pack('f',one))[0])
'0x3f800000'
>>> hex(struct.unpack('I',struct.pack('f',ratio))[0]) <== Mantissa decreased by one bit
'0x3f7fffff'
>>> hex(struct.unpack('I',struct.pack('f', ratio*ratio ))[0]) <== Mantissa decreased by another bit
'0x3f7ffffe'
>>> hex(struct.unpack('I',struct.pack('f',one/ratio))[0]) <== Mantissa increased by one bit
'0x3f800001'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.015)))[0])
'0x3c75c28f'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.016)-numpy.float32(0.001)))[0])
'0x3c75c290'
>>> hex(struct.unpack('I',struct.pack('f', (numpy.float32(0.016)-numpy.float32(0.001)) * ratio ))[0]) <== Multiplying by ratio decreases mantissa by one bit; lower limit is now <= 0.015
'0x3c75c28f'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.017)))[0])
'0x3c8b4396'
>>> hex(struct.unpack('I',struct.pack('f',numpy.float32(0.016)+numpy.float32(0.001)))[0])
'0x3c8b4396'
>>> hex(struct.unpack('I',struct.pack('f', (numpy.float32(0.016)+numpy.float32(0.001)) / ratio ))[0]) <== Dividing by ratio increases mantissa by one bit; upper limit is now >= 0.017
'0x3c8b4397'
-
It may still be some hard-to-do to find a person who's fluent in written and oral (just refer to China, don't know much situation of other regions), but it depends, case by case and people by people. Able to communicate inter-language is okay to me, but people tend to wish they could do better, that's also the factI deal with international salespeople and engineers that always apologize for their English and think they are terrible. I point out that they speak English better than half the people I know born here.
BTW the PLC platform is AB CLX (rev 30), single-precision floating point REAL datatype is used
SUB target_value tolerance lower_limit MUL lower_limit 16777215.0 lower_limit DIV lower_limit 16777216.0 lower_limit
ADD target_value tolerance upper_limit MUL upper_limit 16777216.0 upper_limit DIV upper_limit 16777215.0 upper_limit