I have a float-type-field which contains big number (more than 20 digits). Then I want to convert it to varchar, without rounding. I tried several queries, but nothing.
Here is for example :
SELECT CAST(A AS VARCHAR(25)) AS B
, TRIM(TRAILING '.' FROM CAST(CAST(A AS DECIMAL(25)) AS VARCHAR(25))) AS C
, TRIM(LEADING '0' FROM CAST(CAST(A AS FORMAT '9(25)') AS VARCHAR(25))) AS D
FROM ( SELECT CAST(79999999999999999999.000 AS FLOAT) A ) t0
And the result
B : 8.00000000000000E 019
C : 80000000000000000000
D : 80000000000000000000
I expect to get '79999999999999999999'
Any advises are appreciated.
When you run SELECT CAST(79999999999999999999.000 AS FLOAT) you get 80.000.000.000.000.000.000,000 as result. The precision of a FLOAT is 15 to 16 digits, your input has 20 significant digits, so it's already rounded during the typecast.
As you can't store numbers like this in a Teradata FLOAT the question is: Where's this "float-type-field" coming from? Oracle?
Is there a know maximum n for fractional digits? Then CASTing as DECIMAL(38,n) might be ok.
What's your TD release? 14 introduced the NUMBER datatype to easy porting from Oracle.
NUMBER might be used as a "float-type-field" with approx. 38 digits.
Related
Let's say I have a simple measure like this:
SimpleMeasure = MyTable[Column1]/MyTable[Column2]
Is it possible to have the number of displayed decimals dependent on the value? For example, if my measure calculates the number 500, then I don't want to see 500.00 but rather 500. However if my measure calculates 0.56, then I want to see the value displayed like that to two decimal places and not rounded to the number 1.
So a possible visualization table would look like this:
Store SimpleMeasure
00 10
01 18
02 0.67
03 6
Thank you in advance!
IF(
[SimpleMeasure] < 1, FORMAT([SimpleMeasure], "#,##0.##",
FORMAT([SimpleMeasure], "#,##0")
)
You can use the Switch() function. It will return the first True result. Put you values in a DESC order - start with the largest value, then come to a lower and then to the lowerest. For example :
Switch(
True
,[SimpleMeasure]<1,Round([SimpleMeasure],2) -- 0.655->0.66
,[SimpleMeasure]>999,Round([SimpleMeasure],-2) --1044->1000
,[SimpleMeasure]>499,Round([SimpleMeasure],-1) -- 505,5->510
,[SimpleMeasure]>99,Round([SimpleMeasure],0) -- 101,55->102
,[SimpleMeasure]>1,Round([SimpleMeasure],1) -- 99,43->99.4
)
Or/and you can use in the Switch() the Format() function, with or instead of Round() like:
Format([SimpleMeasure],"#,##0.#")
Or
Format(Round([SimpleMeasure],1),"#,##0.#")
-- Both of them Format() will return and show 99,43 as 99,4.
-- Placeholer # returns a digit or nothing.
-- Placegholder 0 returns a digit or 0.
Usage of Format() and Round() depends on your task. But for a selective Fomat you will need the Switch().
Hope, the answer will help you solve the case
I am trying to format a number to a certain number of digits (7, actually) like the following:
215.5745
6.569674
16.42418
According to this page ("F, D, E, and G Format Codes"), the possible format code would be:
[n]F[+][-][w][.d]
The variable w specifies the number of digits to be transferred
which appears to be exactly what I am looking for.
I understand that the d parameter should not be provided as this would cause the number of decimal positions to be fixed, and could be omitted since:
d is an optional width specification
However, gfortran refuses to compile when a format code like "F7" is provided.
Error: Period required in format specifier in format string at (1)
The linked page appears to be over-simplified or straight-out incorrect. The period is indeed obligatory. The number the period must be non-negative (positive or zero).
I do not think you can do exactly what you require using these format descriptors. Instead, I would first print the number into a string and then only print the first 8 digits of that string - but it is not accurate because it just cuts the remaining digits instead of rounding them.
If you need to be precise, you will have to count the digits before the comma and set-up the format string manually. There won't be a universal format string to use as far as I am aware.
double precision :: a(3) = [215.5745d0,6.569674d0,16.42418d0]
integer :: digs(3)
character(20) :: form
digs = log10(a) + 1
do i = 1, 3
write(form,'(a,i0,a)') "(f8.", max(min(7-digs(i),7),0), ")"
print form, a(i)
end do
end
I think the g0.7 formatting spec should give you exactly what you want.
here is a small test code for formatting.
print '(1x,a24,1x,a24,1x,a24)', "g24.7", "e24.7", "f24.7"
do i=1, n
print '(1x,g24.7,1x,e24.7,1x,f24.7)', a64(i), a64(i), a64(i)
end do
and the sample output
As you can see the gw.7 type of format retains a certain number of significant digits which is what your example shows. But if this is not possible, then it reverts to scientific formatting.
g24.7 e24.7 f24.7
0.3710828E-02 0.3710828E-02 0.0037108
8.318075 0.8318075E+01 8.3180745
33.02631 0.3302631E+02 33.0263091
133.7840 0.1337840E+03 133.7839844
152.5674 0.1525674E+03 152.5673802
274.5596 0.2745596E+03 274.5595695
317.6714 0.3176714E+03 317.6713521
452.4193 0.4524193E+03 452.4193376
646.8024 0.6468024E+03 646.8024139
1117.582 0.1117582E+04 1117.5816049
1384.222 0.1384222E+04 1384.2222737
5529.837 0.5529837E+04 5529.8374344
6555.235 0.6555235E+04 6555.2346832
24251.70 0.2425170E+05 24251.6980498
27283.39 0.2728339E+05 27283.3873660
167907.9 0.1679079E+06 167907.8873403
270053.5 0.2700535E+06 270053.4615256
317435.1 0.3174351E+06 317435.0603955
586812.5 0.5868125E+06 586812.5125615
3538679. 0.3538679E+07 3538679.3597321
I'm trying to read the following rows out of a CSV file stored in GCS
headers: "A","B","C","D"
row1:"4000,0000000000000","15400000,000","12311918,400000","3088081,600"
row2:"5000,0000000000000","19250000,000","15389898,000000","3860102,000"
The issue here is how BigQuery is actually interpreting and thus outputting these numbers:
Results query number 1
It's interpreting A as FLOAT64, and B, C and D as INT64, which is okay since I decided to use autodetect schema. But when I try to convert it to a different type it's still outputting the numbers unproperly.
This is the query:
SELECT
CAST(quantity AS INT64) AS A,
CAST(expenses_2 AS FLOAT64) AS B,
CAST(cexpenses_3AS FLOAT64) AS C,
CAST(expenses_4 AS FLOAT64) AS D
FROM
`wide-gecko-289100.bqtest.expenses`
These are the results of query above:
Result query number 2
Either way, it's misinterpreting how to read the numbers, it should be as follows:
row1: [4000] [15400000] [12311918,4] [3088081,6]
row2: [5000] [19250000] [15389898] [3860102]
Is there a way to solve this?
This is due to BigQuery not understanding the localized format you're using for the numeric values. It expects the period (.) character for the decimal separator.
If you can't deal with this early in the process that produces the CSV files in BigQuery, another strategy is to instead use a string type for the columns, and then do some manipulation.
Here's a simple conversion example that shows some string manipulation and casting to get to the desired type. If you're using both commas and periods as part of the localized format, you'll need a more complex string manipulation.
WITH
sample_row AS (
SELECT "4000,0000000000000" as A, "15400000,000" as B,"12311918,400000" as C,"3088081,600" as D
)
SELECT
A,
CAST(REPLACE(A,",",".") AS FLOAT64) as A_as_float64,
CAST(CAST(REPLACE(A,",",".") AS FLOAT64) AS INT64) as A_as_int64
FROM
sample_row
You could also generalize this as a user defined function (temporary or persisted) to make it easier to reuse:
CREATE TEMPORARY FUNCTION parseAsFloat(instr STRING) AS (CAST(REPLACE(instr,",",".") AS FLOAT64));
WITH
sample_row AS (
SELECT "4000,0000000000000" as A, "15400000,000" as B,"12311918,400000" as C,"3088081,600" as D
)
SELECT
CAST(parseAsFloat(A) AS INT64) as A,
parseAsFloat(B) as B,
parseAsFloat(C) as C,
parseAsFloat(D) as D,
FROM
sample_row
I think this is an issue with how BigQuery interprets a comma. It seems to detect it as a thousands separator rather than a decimal.
https://issuetracker.google.com/issues/129992574
Is it possible to replace with a "." instead?
I am trying to create an IF statement formula in excel that converts minutes to days and hours depending on the amount. Then rounds the value to 1 or 2 decimal points and adds the descriptive text (days, hours, etc) to the end
I have tried the following which converts and adds text but does not round:
=IF(L15>=1440, CONVERT(L15,"min","day") & CONCATENATE(L15," days"),
IF(L15>=60, CONVERT(L15,"min","hr") & CONCATENATE(L15," hours"),
IF(L15<=59, CONVERT(L15,"min","min") & CONCATENATE(L15," mins"))))
I would adjust your formula as follows and based on you wanting to round the final number
=IF(L15>=1440,ROUND(L15/1440,2)&" days",IF(L15>=60,ROUND(L15/60,2)&" hours",ROUND(L15,2)&" minutes"))
the ,2 in the ROUND function tell excel how many decimal places to calculate to. if format is set to general, trailing 0s will not be displayed. If you only want 1 decimal calculation then change the ,2 to ,1.
I currently have a string of values which I retrieved after filtering through data from a csv file. ultimately I had to do some filtering of the data but I have the same numbers as a list, dataframe, or array. I just need to take the numbers in the string and convert them to hex and then take the first 8 numbers of the hex and convert that to dec for each element in the string. Lastly I also need to convert the last 8 of the same hex and then to dec as well for each value in the string.
I cannot provide a snippet because it is sensitive data, but here is an example.
I basically have something like this
>>> list_A
[52894036, 78893201, 45790373]
If I convert it to a dataframe and call df.dtypes, it says dtype: object and I can convert the values of Column A to bool, int, or string, but the dtype is always an object.
It does not matter whether it is a function, or just a simple loop. I have been trying many methods and am unable to attain the results I need. But ultimately the data is taken from different csv files and will never be the same values or list size.
Pandas is designed to work primarily with integers and floats, with no particular facilities for hexadecimal that I know of, but you can use apply to access standard python conversion functions like hex and int:
df=pd.DataFrame({ 'a':[52894036999, 78893201999, 45790373999] })
df['b'] = df['a'].apply( hex )
df['c'] = df['b'].apply( int, base=0 )
Results:
a b c
0 52894036999 0xc50baf407 52894036999
1 78893201999 0x125e66ba4f 78893201999
2 45790373999 0xaa951a86f 45790373999
Note that this answer is for Python 3. For Python 2 you may need to strip off the trailing "L" in column "b" with str[:-1].