In Progress 4GL, is there a way to convert a string to a decimal without any loss in precision? - type-conversion

Say that I needed to turn the character variable "0.0000000001" into a decimal. But if I were to write out the following logic:
define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum as decimal no-undo.
assign tinyNum = decimal(tinyChar).
display tinyNum.
It produces this result:
0.00
So that must not be the solution, and truncating would also just remove the data I'm trying to preserve. Does anyone know how I can preserve the precision of small decimal numbers? It doesn't have to be this crazy case here to the ten-billionth place, but having at least 7 or 8 numbers of precision would help with my issue.

Variables (the DEFINE VARIABLE statement) default to the maximum of 10 decimal places so you do not need to actually declare the precision.
Your problem is really that the DISPLAY format is decoupled from the internal data representation and precision (this is also true for lots of other field and variable attributes like character string width).
This is a feature. But one that people new to OpenEdge often trip over. It is very common to think that the display format constrains the storage of the field or variable. It does not. (Much to the chagrin of anyone using SQL to access the data.)
You can either change the variable's default format as Mike indicates by changing the DEFINE VARIABLE, or you can override the format in any individual DISPLAY.
So the minimum change needed to your code is:
define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum as decimal no-undo.
assign tinyNum = decimal(tinyChar).
display tinyNum format "9.9999999999".
Regardless of the DISPLAY format any calculations you might do with the variable will use all 10 decimal places.
Decimal fields defined in a database schema (as opposed to variables) default to 2 decimal places. You can change that when you create them.
Calculated values assigned to a decimal field or variable will be ROUNDED to the precision defined.

Per the doc[1] the DECIMAL type stores up to 10 decimal places. If you have more, I think it truncates the value.
[1] https://docs.progress.com/bundle/openedge-abl-reference-122/page/DEFINE-VARIABLE-statement.html

Try using the DECIMALS and FORMAT options when you define the DECIMAL variable:
define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum as decimal no-undo
DECIMALS 10 FORMAT "9.9999999999".
assign tinyNum = decimal(tinyChar).
display tinyNum.

Consider converting it by multiplying with a constant (1000000 or something similat). Perhaps even make it an integer?
Progress will not be the best environment for such small floating point numbers. If you depend on the calculations precision will suffer!

Related

Understanding the datatype Double

I am trying to write a program in C to get the percent of even numbers in an array. I am thinking of writing it using int datatype. But some one mentioned to me using double will be easier. I don't understand that. Can anyone guide me with it?
What does double datatype return?
Can the return statement be given as return (double)? What will that give?
Can double convert a real number to a percent? Eg: 0.5 to 50.0
The int datatype is, as the name would suggest, integers (or whole numbers). So you cannot represent a decimal like 0.5. A double is decimal number. So you can hold numbers like 0.5. Common practice is to store your percentage as a simple decimal number like 0.5 (using the double type). Then when you need to display nicely as 50.0%, just multiply by 100 before displaying.
Here's a useful link on C's basic datatypes: http://www.tutorialspoint.com/ansi_c/c_basic_datatypes.htm

Number of decimal digits to show

How to change the number of decimal digits?
Changing the format Matlab can show only 4 (if short) or 15 (if long). But I want exactly 3 digits to show.
To elaborate on Hamataro's answer, you could also use roundn function to round to a specific decimal precision, e.g.: roundn(1.23456789,-3) will yield 1.235. However, Matlab will still display the result in either of the formats you have mentioned, i.e 1.2350 if format is set to short, and 1.235000000000000 if format is set for long.
Alternatively, if you use sprintf, you can use the %g formatting option to display only a set number of digits, regardless of where the decimal point is. sprintf('%0.3g',1.23456789) yields 1.23; sprintf('%0.3g',12.3456789) yields 12.3
You can either use sprintf or do *
var2 = round(var1*1000)/1000

Can the Postgres data type NUMERIC store signed values?

In PostgreSQL, I would like to store signed values -999.9 - 9999.9.
Can I use numeric(5.1) for this?
Or what type should I use?
You can certainly use the arbitrary precision type numeric with a precision of 5 and a scale of 1, just like #Simon commented, but without the syntax error. Use a comma(,) instead of the dot (.) in the type modifier:
SELECT numeric(5,1) '-999.9' AS nr_lower
, numeric(5,1) '9999.9' AS nr_upper;
nr_lower | nr_upper
----------+----------
-999.9 | 9999.9
The minus sign and the dot in the string literal do not count against the allowed maximum of significant digits (precision).
If you don't need to restrict the length, just use numeric.
If you need to enforce minimum and maximum, add a check constraint:
CHECK (nr_column BETWEEN -999.9 AND 9999.9)
numeric stores your number exactly. If you don't need the absolute precision and tiny rounding errors are no problem, you might also use one of the floating point types double precision (float8) or real (float4).
Or, since you only allow a single fractional decimal digit, you can multiply by 10 and use integer, which would be the most efficient storage: 4 bytes, no rounding errors and fastest processing. Just use and document the number properly.
Details for numeric types in the manual.

how I must use digits function in matlab

i have code and use double function several time to convert sym to double.to increase precision , I want to use digits function.
I want to know it is enough that I write digits in the top of code or I must write digits in above of every double function.
digits set's the precision until it is changed again. Calling digits() without any input you get the precision to verify it's set correct.
In many cases digis has absoluetly no influence on symbolic variables because an analytical solution is found. This means there are no precision errors unless you convert to double. When convertig, digits should be set to at least 16 because this matches double precision.

SSRS graph with optional decimal positions

Is is possible to show optional decimal numbers for the values in the graph? I want to show up to 2 decimal values but only if the user inputs them. If the value is 9.34, I want it to show that. But if the value is just 9, I want it to show just 9. If the users types 9.3 then only that should be shown.
You can accomplish that by converting the decimal value to a string and then using format characters like this:
=Format(CStr(Fields!a.Value),"#.##");
The # character will only diplay if a decimal value exists. ( fyi, if you wanted the opposite from the format string, using 0.00 would force display zero's even if the values were integers ).
You can also use a combination such as 0.## or 0#.##
Further:
You can also just place that format string in the Custom option under Number in properties.