I have a large text file with no headers with fields delimited by a fixed width. All numeric fields are padded with zeros. I want to import this into Alteryx using field settings from a flat file.
Some of my fields should have the format Fixed Decimal, for example the "Regular Cost" column is a fixed decimal 9.04 - 5 decimal places before the decimal point and four following. Input example is "000026300". Desired output is 2.63.
I can't figure out the Length and Scale requirements for this to work.
Length = 9, Scale = 4 gives the error
Regular Cost: "000023600.0000" was too long to fit in this FixedDecimal.
Example image
Apparently it doesn't like the missing decimal point. If you read the file as a string, then add the decimal to the correct location in the string, e.g. read it in and force the field length to 10, then use the formula...
Left([Field_1],5) + "." + Left(Right([Field_1],4),3)
... it will look as expected. Then you can map it to a Double or a FixedDecimal 10.4
Related
I would like to print a series of floats with varying amounts of numbers to the left of the decimal place. I would like these numbers to exactly fill a padding with blank spaces, digits, and a decimal point.
Paraphrasing the data and code I have now
floats = [321.1234561, 21.1234561, 1.1234561, 0.123456, 0.02345, 0.0034, 0.0004567]
for number in floats:
print('{:>8.6f}'.format(number))
This outputs
321.123456
21.123456
1.123456
0.123456
0.02345
0.0034
0.000457
I am looking for a way to print the following in a for loop assuming I don't know the amount of digits that will be to the left of the decimal place and the number of digits to the left never exceeds the padding which is 8 for this example.
321.1234
21.12345
1.123456
0.123456
0.02345
0.0034
0.000457
Similar questions have been asked about printing floating points with a certain width but the width they were talking about appeared to be the precision rather than the total number of character used to print the number.
Edit:
I have added a number to the end of the list for the following reason. The use of the specifier 'g' with 7 significant figures was recommended by attdona. This prevents the padding from being exceeded for numbers greater than or equal to 1 but not for numbers less than 1 with precision greater than 6. Using {:>8.7g} instead gives
321.1234
21.12345
1.123456
0.123456
0.02345
0.0034
0.0004567
Where the only one that exceeds the padding is the newly added one.
Use the General format type specifier g:
'{:>8.7g}'.format(number)
reference: https://docs.python.org/3/library/string.html#format-specification-mini-language
Update: For small numbers this format fails to align correctly. In this case you may adopt a mixed approach, but keep in mind that very small numbers will round to zero
for number in floats:
fstr = '{:>8.7g}'.format(number)
if len(fstr) > 8:
fstr = '{:>8.6f}'.format(number)
print(fstr)
for i in floats:
print('{:>8}'.format(f'{i:{8}.{8-len(str(int(i)))-1}f}'.rstrip('0')))
321.1235
21.12346
1.123456
0.123456
0.02345
0.0034
The csv file is generated by java program. The file I open notepad++, the values are in 2 decimal places as in the picture above shown. But when I open the file in excel, some values which less than thousand is not in 2 decimal places format.
Why it behaves like that?
Code is like.
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
symbols.setDecimalSeparator('.');
DecimalFormat formatter = new DecimalFormat("#,###.00", symbols);
fileWriter.append(String.valueOf(detailsContent.getAppliedAmount() == null ? "" : "\"" + formatter.format(new BigDecimal(detailsContent.getAppliedAmount()).setScale(2, BigDecimal.ROUND_DOWN)) + "\""));
fileWriter.append(String.valueOf(detailsContent.getAmountSaving() == null ? "" : "\"" + formatter.format(new BigDecimal(detailsContent.getAmountSaving()).setScale(2, BigDecimal.ROUND_DOWN)) + "\""));
With the numbers that are greater than 1000, Excel sees that the string from the CSV uses a thousand separator character, so it applies a number format to the cell. It takes its cue from the text, i.e. thousand separator and two decimals. If there were no thousand separator in the source, Excel would apply the General format.
With the smaller numbers, Excel applies the General format, which will omit zeros as decimals. The fact that the source file has two decimals is not a sufficient trigger for Excel to apply a specific number format.
I'm trying DEC2HEX(1000000000050000000) but it comes out as #NUM! as the number is too large for this function.
Is there another function I could use to turn this number into hexadecimal?
If you want to convert a decimal number to a 64 bit hex string, assuming that the decimal number is in cell A1 you can use the following:
=CONCATENATE(DEC2HEX(A1/2^32),DEC2HEX(MOD(A1,2^32),8))
This will work up to decimal value of 18,446,744,073,709,500,000 or hex value of 0xfffffffffffff800.
Bonus:
To convert from hex string to decimal, assuming that the 64bit hex string is in cell A1 and contains 16-characters then you can use the following:
=HEX2DEC(LEFT(A1,8))*2^32+HEX2DEC(RIGHT(A1,8))
You can adjust the number of characters in the LEFT(text,[num_chars]) to better suit your needs.
If your hex string has a 0x then you can use the following:
=HEX2DEC(MID(A1,3,8))*2^32+HEX2DEC(RIGHT(A1,8))
I found a simple solution for converting HEX to DEC and vice versa without the limits of characters.
HEX to DEC: use DECIMAL(input number or cell coordinates, input base number)
Case 1: I want to convert hex value "3C" to decimal, the formula is DECIMAL(3C, 16).
Case 2: I want to convert binary value "1001" to decimal, the formula is DECIMAL(1001, 2).
DEC to HEX: use BASE(input number or cell coordinates, output base number)
Case 1:I want to convert number value "1500" to hexadecimal, the formula is BASE(1500, 16)
Case 2:I want to convert number value "1500" to binary, the formula is BASE(1500, 2)
The DEC2HEX function has a limit of 549,755,813,887, try this formula it works for numbers up to 281,474,976,710,655.
=DEC2HEX(A7/(16^9),3)&DEC2HEX(MOD(A7,16^9),9)
There is a free add-in available that will handle that: Xnumbers
Seems to work OK:
=cvDecBase("1000000000050000000",16) --> DE0B6B3AA5EF080
Long formula but it is working for 64-HEX characters:
=HEX2DEC(MID(A24,1,8))*2^512 *(4) +HEX2DEC(MID(A24,9,8))*2^512 *(2) +HEX2DEC(MID(A24,17,8))*2^512+HEX2DEC(MID(A24,25,8))*2^256+HEX2DEC(MID(A24,33,8))*2^128+HEX2DEC(MID(A24,41,8))*2^64+HEX2DEC(MID(A24,49,8))*2^32+HEX2DEC(MID(A24,57,8))
please note: (*4) = *4 (remove brackets) and: (*2) = *2 (remove brackets)
also note: all 64 character must be present like the following example:
0000000000000000000000000000000000000000000000000000000000000fd1
I just started studying pascal and I have to do a pascal program as homework.
I made it but I don't know how to count the number of decimal places in a real number (the number of digit after the ".").
I need it just to format well a real number (like write(real:0:dec) where dec is the number of decimal digit i don't know how to know). I'd like to do that because i don't want it in scientific notation or with many unnecessary zeros.
For example if a real number is 1.51 (x) and I write writeln(x:0:4); or WriteLn(Format('%*.*f', [0, 4, x])); it will show 1.5100 but I want it to be just 1.51; and if the number is like 1.513436, it will show only 1.5134 . So I would make it like writeln(x:0:dec); with something that makes dec the number of decimal digits of x.
The Format() function is normally used in situations like this.
WriteLn(Format('%*.*f', [0, dec, your_real_number]));
*.* is interpreted as total_characters.decimal_digits. Passing zero for the first means that width is adjusted according to how large your real is. The number of decimals can be a variable (dec), which you can adjust to your specification.
Update:
You mention that you want an exact representation of a float with respect to the number of decimals.
As mentioned in my comment, most floating point values does not have a finite number of decimals. And most decimal fractions cannot be represented by a binary type.
There are some libraries that can handle floating point values of arbitrary size. See TBigFloat for example. There is a formatting routine that can strip redundant zeroes from a decimal float.
Still, there is a possibility to remove trailing zeroes by using the general format specifier:
WriteLn(Format('%g',[your_real_number]));
You can specify the width and the number of significant digits as well.
For example, if you have input x=1.51 in real variable type, then you write only writeln(x), the output will be 1.5100000000. If you write writeln(x:0:3), the output will be 1.510 (3 digits after ".") ...
var x: real;
Begin
x:=1.51;
writeln(x); //output 1.5100000000
writeln(x:0:4); //output 1.5100 (4 digits after ".")
writeln(x:0:2); //output 1.51 (2 digits after ".")
readln;
End.
From your other example, if your input is 1.512426, with writeln(x:0:5) it will only show 5 digits after "." and the output will be 1.51242
var x: real;
Begin
x:=1.512426;
writeln(x); //output 1.5124260000
writeln(x:0:4); //output 1.5124 (4 digits after ".")
writeln(x:0:2); //output 1.51 (2 digits after ".")
readln;
End.
So, if you write writeln(x:0:dec) the output will be "dec" digits after "."
Hope this helps, I'm just trying to answer from a different perspective.
if you're actually doing a writeln() output, surely just
writeln(x);
would accomplish what you're after? If you actually want to count the number of decimals, you'd probably have to convert to a string, remove any trailing zeroes, and see where the decimal point landed.
I am putting a string into excel. The string is often only numeric digits but can have alpha characters or hypens etc.
When I don't set the number format or set it like this
(Where xlSheet(0) is Excel.Worksheet)
xlSheet(0).Columns("N:N").EntireColumn.Columns.NumberFormat = "#"
It outputs in scientific notation.
When I use this code:
xlSheet(0).Columns("N:N").EntireColumn.Columns.NumberFormat = "0"
It rounds up the number to the nearest 100,000 so that the last five digits are 0's when they shouldn't be.
Should be: 1539648751235678942
But is: 1539648751235600000
The cells that have a hyphen or a letter aren't affected and work fine.
Any help would be greatly appreciated.
EDIT:
I add the data like this:
I loop through and put in xlSheet(0).Cells(i, 14) = rs!value_number
Where rs is my ADODB.Recordset
EDIT2: Herbert Sitz got it by adding an apostrophe before the text! Thanks everyone.
I think problem is that the number you're trying to enter can't be accommodated exactly by Excel. Excel has limitations on what numbers it display/represent because of the way numbers are stored internally. In Excel's case numbers are limited to 15 digit precision (see http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP010073849.aspx ), which is not enough to represent your number.
You can enter the number as a string ("152..42") and all digits will be displayed, but you won't be able to perform exact mathematical operations with it.
For numbers, Excel can only handle 15 significant digits.
If you want to store a number that is more than 15 digits long without losing data, you have to store the data as text.
Doing what you've been doing will resolve the issue:
You can do either of the following to add your numbers as text:
xlSheet(0).Cells(i, 14).Numberformat = "#"
xlSheet(0).Cells(i, 14) = rs!value_number
Or
xlSheet(0).Cells(i, 14) = "'" & rs!value_number