Is there a way to specify the numeric format when storing a DECIMAL as STRING?
Currently, using the STRING() function on a DECIMAL uses the session's numeric format to store the value, which creates a value that is not session independent.
Is there a way to store a decimal in a string using a specific numeric format, or a numeric format independent way?
Answering myself.
DEFINE VARIABLE Pi AS DECIMAL NO-UNDO INITIAL 3.14159.
DEFINE VARIABLE PiString AS CHARACTER NO-UNDO.
/* Store as American format decimal string */
ASSIGN PiString = REPLACE(STRING(Pi), SESSION:NUMERIC-DECIMAL-POINT, ".":U).
/* Restore as decimal */
ASSIGN Pi = DECIMAL(REPLACE(PiString, ".":U, SESSION:NUMERIC-DECIMAL-POINT)).
Answering myself.
DEFINE VARIABLE Pi AS DECIMAL NO-UNDO INITIAL 3.14159.
DEFINE VARIABLE PiString AS CHARACTER NO-UNDO.
/* Store as American format decimal string */
ASSIGN PiString = REPLACE(STRING(Pi), SESSION:NUMERIC-DECIMAL-POINT, ".":U).
/* Restore as decimal */
ASSIGN Pi = DECIMAL(REPLACE(PiString, ".":U, SESSION:NUMERIC-DECIMAL-POINT)).
One might observe that this is exactly why one should store a decimal as a decimal.
In the end a conversion always happens at one point or another when outputting/reading to/from file/json/xml/... so keeping as decimal can only be done to a certain extent...
Yes, but those are all I/O operations where one expects to have to do such things. If a field is conceptually decimal, it should be stored as a decimal.
Values of all 4GL datatypes are stored in the database (and in 4GL runtime's local memory) in a format neutral and processor architecture neutral form. The supported numeric types are integer, decimal and float and each has its own storage format.
The values of type decimal are stored as a string of 4-bit “nibbles” preceded by a length byte and a "control byte”. Each nibble represents one digit of the value.
The control byte is, if negative, the number of digits to the right of the decimal point. If positive, then digits to the left of the decimal point + 0x80. The maximum number of digits is 32.
The display format has nothing at all to do with the storage format. This is a good thing. You should store decimal values as a value of type decimal, not something else like string.
When converting values from decimal storage to text, use whatever format is suitable for your intended use.
I think he is receiving an American XML and processing it on a European computer in which a string representation of a decimal value has to be converted to the proper region first before it can be stored correctly.
[quote user="Thomas Mercer-Hursh"]
Yes, but those are all I/O operations where one expects to have to do such things. If a field is conceptually decimal, it should be stored as a decimal.
[/quote]
The OP said "Is there a way to specify the numeric format when storing a DECIMAL as STRING?" I read that as *storing decimal as string*, not an I/O conversion operation.
jquerijero's answer disappeard, but I got it by mail:
[quote user="jquerijero"]
I think he is receiving an American XML and processing it on a European computer in which a string representation of a decimal value has to be converted to the proper region first before it can be stored correctly.
[/quote]
Off course for regular use a decimal value is stored in a decimal variable/decimal field, that's not the discussion/point here, that is obvious.
By storing I meant in a character variable. That variable could contain more than just the single decimal. This variable could be stored in a db character field, containing arbitrary data, or to a file, or sent through a socket...
[quote user="gus bjorklund"]
When converting values from decimal storage to text, use whatever format is suitable for your intended use.
You could easily put the stringification in a function and set the desired session format there or do the replacements there, but I guess I have to wonder why, if the current function is intended to have a particular format, you don't just set the session format for the whole thing. I..e., the format is part of the context.
Hi Thomas,
Yes, I've added the code in a helper class method to do the replacement.
The whole idea is that the string can be read/written in sessions that have different numeric-format settings. I won't force some setting to the session of the user, people in Europe want to use comma's instead of points as decimal separator.