Diese Seite mit anderen teilen ...

Informationen zum Thema:
Forum:
WinDev Forum
Beiträge im Thema:
12
Erster Beitrag:
vor 4 Jahren, 11 Monaten
Letzter Beitrag:
vor 4 Jahren, 11 Monaten
Beteiligte Autoren:
GuenterP, RAUL2, Steven Sitas, Fabrice Harari, Peter Holemans

Why Reals are really dangerous !!!!

Startbeitrag von Steven Sitas am 06.09.2013 14:27

for a long time there has been an example called "WD Number in Words" in the English Windev product ..
I modified the procedures from this example - to support Greek - and I used them in all my apps for a long time. Everything worked fine for many years until today ...
I got a call from a customer saying that a numeric 34087,29 got translated in words to 34087,28.
After some investigating and debugging I saw that everything that had .29 (like 2345,29 - 0,29 - 5,29 etc) got translated to a 0,28.
Every other decimal - except 0,29 - worked fine !!!!!!

The problem was that the above example in Windev versions 16, 15 and back used a REAL variable in the code that equalled 0,29 *10^2 to 28 instead of 29 !!!!

This has been fixed in the WinDEV 17 examples and later, using Numeric instead of Real variable.

So if anyone is using code from the above example and copied it a long time ago, look at it again !!!!

Steven Sitas

Antworten:

Hi Steven,

reals are here since the earliest programming languages have been devised. Programmers using FORTRAN, BASIC and many more languages had just integers and 4-byte / 8-byte reals, named 'floating point variables' then, in their tool case. Much later, together with COBOL the first BCD-numerics (binary coded decimals) appeared.

Means, these precision problems / rounding problems of 'reals' are well-known to those of us who are working in the software industry for some decades. The nature of a float is that storing 123456.123 on disk will not yield exactly the same value when read from disk again. In nearly no case! If reals are used then you will need
1 - to use the right precision of reals. Nowadays: use 8-byte reals. We used to use 4-byte reals which are saving some space on disk, which is no issue with terabyte disks. In the 60s and 70s this had been an issue.
2 - to use a proper rounding algorithm. Inevitably, a programmer had to invent her/his own rounding algorithms when using reals within commercial software.

Just for historical interest, three of my BASIC rounding algorithms looked like these here:


DEF FNRD4! (I!) = SGN(I!) * (FIX((ABS(I!) * 10000) + .50001)) / 10000
DEF FNRD# (I#) = SGN(I#) * (FIX((ABS(I#) * 100) + .50001)) / 100

DEF FNRD!(I!)
RUX$ = FUsing$(STR$(I!),"#######.#######")
FOR RUI% = 15 TO 11 STEP -1
IF VAL(MID$(RUX$,RUI%,1)) > 4 THEN
I! = I!+VAL("0."+STRING$(RUI%-10,"0")+"1")
RUX$ = FUsing$(STR$(I!),"#######.#######")
MID$(RUX$,RUI%,16-RUI%) = STRING$(16-RUI%,"0")
ELSE
MID$(RUX$,RUI%,1) = "0"
END IF
NEXT RUI%
FNRD! = VAL(RUX$)
END DEF


I could translate these to WLanguage but you're better off to simply use (BCD)-numerics instead. However, it's easy to understand that younger members of the trade aren't familiar with the (then necessary) tricks of earlier times.

von GuenterP - am 07.09.2013 05:45
Hi Guenter,
I also never use Reals in my programming ...
It was just STUPID of me to use somebody elses code (PC Softs example) without first taking a close look at it !!!!

Just posted this, so if anybody had used "as is" the above code, he/she would correct it.
And of course it is a GREAT example for young programmers, about what can go wrong with REALs.

Steven Sitas

von Steven Sitas - am 07.09.2013 09:16
So the advise is never use 4 bytes reals? Can you say 8 bytes reals are ok? I've found another thread where someone suggests to use currency instead of reals.

Guenter: if I understand correctly, you're suggesting to use numerics instead of coding a rounding the above algorithm?

Regards.

von RAUL2 - am 07.09.2013 23:55
Quote
RAUL2
So the advise is never use 4 bytes reals? Can you say 8 bytes reals are ok? I've found another thread where someone suggests to use currency instead of reals.

Guenter: if I understand correctly, you're suggesting to use numerics instead of coding a rounding the above algorithm?

Regards.


Hi Raul,

generally, reals are not dangerous at all. You just have to know what you're doing and where and how to use them. ;-)

The main problem with them is that e.g. an input into an edit control like 144897.45618 stored as a real on disk and later on retrieved will be never 100% identical to the original input value! The nature (and value) of floating point numerics is that they have a certain number of digits which are precise while they can cover a huge range of values. See: http://en.wikipedia.org/wiki/IEEE_floating_point

From calculations with reals / floats, one cannot expect to get a clear result like 400.000000 * 1200.000000 = 480000.000000 - there will always be some imprecision in the result, generally somewhere after the decimal point. If values are getting bigger ahead of the decimal point, at some time, imprecision will lastly reach out to full digits ahead of the comma. Even using 8-byte reals makes things only better in regards to the number of correct decimal places, but it will never be 100% ok. You have to stay quite a bit away from those decimal places which will be imprecise. Multiplying / dividing two imprecise numbers will clearly result in a much more imprecise result! It's advisable to round both operands before doing a calculation and round the result again. This will enable you to keep imprecisions at bay. Therefore, using reals in commercial programs takes some caution.

However, floats have a clear advantage over other representations of decimals: most processors have a built-in floating point arithmetic unit plus a set of commands dealing with floats. Means, floating-point calculations are much faster than those for currency (a hidden long integer with a library based manipulation of the decimal point) or 'numerics' (simply a hidden BCD, calculations based on a library). Therefore, if your program is calculation-intensive, it is not advisable to use BCD, 'currency' will be a bit faster, floats are the way to go.

von GuenterP - am 08.09.2013 07:38
Hi Guenter, thanks a lot for your explanation.

I have to deliver a POS software soon. For the inventory, I'm using 4 bytes reals. Mostly, the products that this client sells are grocery (e.g. bottled water 1000ml, red wine brand YYYY 750ml, and so on) and the misure is 90% of the time integers (like the examples: bottles). There are some products (like bread for instance) which are sold by Kg. Here es where I need the decimal part of the 4 bytes real.

There is no much calculation. If the client sells 2 bottles of wine and the stock for that wine is 10, now the client have 8. If he sells 1.65 Kg of sugar and previous stock was 12 Kg, now he has 10.35 Kg. That's almost all the calculation regarding the stock. It always will be 2 decimals, no more.

What do you thing about issuing 4 bytes reals? No I see that it can happen what Steven says: if the client sells 1.29 kg of sugar, the software may inform him 1.28!

Best regards.

von RAUL2 - am 09.09.2013 00:18
Hi Raul,

there is a simple rule from old days that I'm still observing in WINDEV: never ever rely on implicit type changes. Which in fact is, what he did.

Integer = Real * Real 0.29 is definitely a float, but does WinDev really interpret the '100' as a real or is it an integer too? If so, it could mean

Integer = Real * Integer

to exclude such funnies automatically, one has to use Reals ONLY in a calculation or use the function Round(...)

I tested this one and it works just fine:

MyReal1 is 4-byte real = 0.29
MyReal2 is 4-byte real = 100
MyInteger1 is 4-byte int
MyInteger2 is 4-byte int

MyInteger1 = MyReal1 * MyReal2
MyInteger2 = Round(MyReal1 * MyReal2,0)

MyInteger1 = 28
MyInteger2 = 29

Here, WinDev is forced to do a type conversion and does it following its own rules. I Believe, there's a warning about this somewhere in the documentation

von GuenterP - am 09.09.2013 06:47
Hi all,

Use the W-Language 'numeric'-type instead. This will alwasy be correct...
The same real (floating point) problem goes for C/C++/Pascal and many other languages.

It is stated in the help pages: http://doc.pcsoft.fr/en-US/?1514048&name=reals&q=real


Problems of precision with the reals

The operations performed on the "real" types are not precise because of the computing representation of the reals.
Two reals that are equal mathematically speaking are not necessarily equal computer-wise and the ">", "" operators (or "=" and "


von Peter Holemans - am 09.09.2013 07:54
I see the point, anyway, if I use 4 bytes reals for these:

* wine bottles, for instance: 1.00
* sugar, for instance: 1.65

Will my simple calculations (stock purposes) will ok? or should I user another field/var type? Maybe 8 bytes real? (even when I'll use only 2 digits in the decimal part), numeric? What do you think?

Regars.

von RAUL2 - am 10.09.2013 01:02
Quote
RAUL2
I see the point, anyway, if I use 4 bytes reals for these:

* wine bottles, for instance: 1.00
* sugar, for instance: 1.65

Will my simple calculations (stock purposes) will ok? or should I user another field/var type? Maybe 8 bytes real? (even when I'll use only 2 digits in the decimal part), numeric? What do you think?

Regars.


Hi Raul,
if you stay with Reals and keep in mind how they're stored, what they're doing, and if you use rounding where appropriate, I do not see a problem in using reals. If your prices / quantities stay below 6 significant places then, there's no problem even wit 4-byte reals. If larger figures are possible, just convert to 8-byte reals.

von GuenterP - am 10.09.2013 09:13
Hi

personnaly, I stopped using reals as soon as currencies became available. Now that we have Numerics, I use those instead.

I do not see ANY advantage of using reals, and potentials pitfalls everywhere. And this is not a wlanguage problem... Reals in wlanguage work the same way than reals in any languages: in order to be able to store more information in less bytes, the "inventors" of th real system decided that skipping some values was okay. I tend to disagree, so I don't use them :-)

Best regards

von Fabrice Harari - am 10.09.2013 11:40
Thanks a lot guys for the answers!
Kind regards.

von RAUL2 - am 10.09.2013 16:51
Zur Information:
MySnip.de hat keinen Einfluss auf die Inhalte der Beiträge. Bitte kontaktieren Sie den Administrator des Forums bei Problemen oder Löschforderungen über die Kontaktseite.
Falls die Kontaktaufnahme mit dem Administrator des Forums fehlschlägt, kontaktieren Sie uns bitte über die in unserem Impressum angegebenen Daten.