Group digits in currency and remove leading zeroes - locale

I want to know how to do
digit grouping
when I have value for money for example 3000000 ( 3million) i want to print 3.000.000 on the screen (there is a dot every three character from the last character)
Remove zeroes in front of value
when I select a value from table and print it on the screen, the value get padded with zeroes automatically: e.g. 129 becomes 0000129

The WRITE statement allows you to specify a currency. Example:
DATA price TYPE p DECIMALS 2.
price = '3000000'.
WRITE: / price CURRENCY 'USD'.
Note that this does not interpret the number itself, but just adds commas and dots at certain positions depending on the currency you specify. So in the event you have an integer with the value of 3000000 and you write it with currency USD the result will be 30.000,00.
I suggest you read the F1 help information on the WRITE statement, because there are a lot more options besides this one.
--
Removing leading zeroes is done by using a conversion routine.
The CONVERSION_EXIT_ALPHA_INPUT will add leading zeroes and CONVERSION_EXIT_ALPHA_OUTPUT will remove them.
It is possible to add these routines to a Domain in the dictionary, so the conversion will be done automatically. For example the MATNR type:
DATA matnr TYPE matnr.
matnr = '0000129'.
WRITE: / matnr.
This will output 129 because the Domain MATNR has a conversion routine specified.
In the case of a type which does not have this, for example:
DATA value(7) TYPE n.
value = '0000129'.
WRITE: / value.
The output will be 0000129. You can call the CONVERSION_EXIT_ALPHA_OUTPUT routine to achieve the output without leading zeroes:
DATA value(7) TYPE n.
value = '0000129'.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
input = value
IMPORTING
output = value.
WRITE: / value.

Please also note that output conversion for numberlike types - triggered by the WRITE statement - is controlled by a property in the user master data.
Decimal separator and digit grouping should be configured there.
You could check this in the user master transactions e.g. SU01 or SU01D.

For removing the zero padding use NO-ZERO statement. For the thousand separator I do not see any problem because it is a standard way ABAP prints values of type P. Here is a sample code.
REPORT ZZZ.
DATA:
g_n TYPE n LENGTH 10 VALUE '129',
g_p TYPE p LENGTH 12 DECIMALS 2 VALUE '3000000'.
START-OF-SELECTION.
WRITE /: g_n, g_p.
WRITE /: g_n NO-ZERO, g_p.
This produces the output.
000000129
3.000.000,00
129
3.000.000,00

For removing leading zeros, you can do the following:
data: lv_n type n length 10 value '129'.
shift lv_n left deleting leading '0'.

Related

How to convert a string to number in scheme without removing the leading zero?

I want to convert a string to a number in Scheme, but when I use the function string->number it removes the leading zero
For example
(string->number "01") gives me 1
Is there a way to convert the string so that it doesnt remove the leading zero and gives me 01 instead?
You can't: leading zeros are just part of the written representation of numbers, not part of the number itself. In particular 01, 1 and 00000001 are all the same number.
If you want to print numbers with leading zeros, for instance to line things up, then there are utilities which do that. For instance in Racket, while the format / printf family of procedures cannot do this, the procedures provided by racket/format can:
> (require racket/format)
> (~a 1 #:width 2 #:align 'right #:pad-string "0")
"01"
However you will still need to deal with negative numbers yourself, which is rather annoying.

How to get first significant figure from a number in Excel?

I have a column of numbers in Excel 2016. The numbers span many orders of magnitude, but are all positive. Some are less than zero. How can I return the first significant figure of each cell in a new column?
For example, for the number 1.9 the result should be 1. For the number 0.9 the result should be 9.
Things I've tried:
Using LEFT() to get the first character. This works for values greater than 1, but for numbers between 0 - 1 it returns 0 (that is, LEFT(0.3, 1) returns 0). I've tried using this with scientific notation formatting and it returns the same result.
I've searched Google and SO for solutions to this problem. There are many posts about rounding to significant figures, but I'm looking to truncate, not round.
Reading through Office's online docs regarding scientific notation.
You could use scientific notation:
=LEFT(TEXT(A1,"0.000000000000000E+00"))
Note: You can only have 15 digits of precision in Excel so this should be OK.
you can multiply the number by a factor of 10 significant enough to deal with any 0 not wanted:
=--LEFT(A1*10^LEN(A1),1)
Read the cell value as text, replace dots and zeros (. / 0) with nothing, return the leftmost "character"; multiply it by 1 to coerce it back into a number:
=LEFT(SUBSTITUTE(SUBSTITUTE(TEXT(A1,"#"),".",""),"0",""))*1
You can also create a custom UDF (User Defined Function) that uses Regular Expressions to accomplish this task. This would require copy/paste VBA knowledge, as well as you setting a reference to:
Microsoft VBScript Regular Expressions 5.5
(which can be done by going to the VBE (Alt+F11), Tools > References. Then check the box of the reference listed above)
Paste the following UDF into a standard code module within the VBE:
Public Function SigNum(ByVal InputNumber As Double) As Long
Dim s As SubMatches
With New RegExp
.Pattern = "\.0*([^0])|^([^0])"
If .test(InputNumber) Then
Set s = .Execute(InputNumber)(0).SubMatches
If s(0) > 0 Then ' This is before the period
SigNum = s(0)
Else
SigNum = s(1)
End If
End If
End With
End Function
On your worksheet, you would be able to use your newly created formula as such:
=SigNum(A1)
You can see what it matches in the example on regex101. When viewing this site, green highlighted numbers are what would be returned if the value is < 0, and red would be what is returned if the value > 0). If the value = 0, this will return 0.
Breaking Down the Pattern
Here's how the pattern \.0*([^0])|^([^0]) works. First, you can see that there is a |, which essentially acts like an Or statement, so we will split these into two sections.
First Section \.0*([^0])
\. will match a literal period. This ensures that we are looking at a value that is less than 0.
0* matches all zeros, 0 to unlimited * times. We use * (zero to unlimited) instead of + (1 to unlimited) because a zero is not required to be in front of the significant number - but the zero itself isn't significant.
[^0] This is a negated character class [^...]. This means it will match anything that is not in this class. Since our significant number should be a value other than zero, we do not want to match a zero. And because it's surrounded by a capturing group (...), this is what is returned back to the function.
Second Section ^([^0])
We've established that since the first section didn't match, then the value must be greater than 0.
^ this is an anchor point that matches the beginning of the string. On the first section we didn't require it because we essentially used the period \. as our anchor. Since our value is greater than 0, we need to ensure we are starting from the absolute left of the input number.
(...) Capturing Group. Anything within this group will be returned as a submatch and ultimately back to the function as it's return value.
[^0] Negated Character class. It will match anything except a 0.

How to print a number within a string in matlab

I would like to use the command text to type numbers within 57 hexagons. I want to use a loop:
for mm=1:57
text(x(m),y(m),'m')
end
where x(m) and y(m) are the coordinates of the text .
The script above types the string "m" and not the value of m. What am I doing wrong?
Jubobs pretty much told you how to do it. Use the num2str function. BTW, small typo in your for loop. You mean to use mm:
for mm=1:57
text(x(mm),y(mm),num2str(mm));
end
The reason why I've even decided to post an answer is because you can do this vectorized without a loop, which I'd also like to write an answer for. What you can do place each number into a character array where each row denotes a unique number, and you can use text to print out all numbers simultaneously.
m = sprintfc('%2d', 1:57);
d = reshape([m{:}], 2, 57).';
text(x, y, d);
The (undocumented!) function sprintfc takes a formatting specifier and an array and creates a cell array of strings where each cell is the string version of each element in the array you supply. In order to ensure that the character array has the same number of columns per row, I ensure that each string takes up 2 characters, and so any number less than 10 will have a blank space at the beginning. I then convert the cell array of strings into a character array by converting the cell array into a comma-separated list of strings and I reshape the matrix into an acceptable form, and then I call text with all of the pairs of x and y, with the corresponding labels in m together on the screen.

I want to extract only last two numeric values from a string variable in SAS

I want to extract only last two numeric values from a string variable and assign it to a new variable. Firstly i have extracted all the numeric values from the string using the code below and assigned it to a new variable but i ultimately want to extract only the last two numeric values so is there any better way to do this.
UI_DUM = input(compress(Prod_Desc,,"kd"),best.);
And one more question is: how to assign a temp variable for doing some manupulation work in SAS?
Here is the code.
You are doing it right, to remove the characters and keeping only digits. The same is being done for variable "temp1"(in the below code).
In the second step, using the length function, to calculate the total length of the string which now contains only digits. In the third step using the substr function to extract the last two digits.
If you want to do it in one statement, "final" variable is the answer.
LENGTH Function - Returns the length of a non-blank character string, excluding
trailing blanks, and returns 1 for a blank character string
compress function with "kd" option - would keep only digits.
COMPRESS(<, chars><, modifiers>)
Modifier - specifies a character constant, variable, or expression in which each non-blank character modifies the action of the COMPRESS function. Blanks are ignored. The following characters can be used as modifiers.
d or D adds digits to the list of characters.
k or K keeps the characters in the list instead of removing them
substr function - Extracts a substring from an argument -
SUBSTR(string, position<,length>)
data _null_;
Test_string="ada13117a1w11da1286s";
temp1=compress(Test_string, , 'kd');
temp2=length(temp1);
temp3=substr(temp1,temp2-1,2);
final=substr(compress(Test_string, , 'kd'),length(compress(temp1))-1,2);
put _all_;
run;
Regarding the temp variable, there is no such one in SAS. Just use any variable name and use the drop statement in final dataset like below;
data test(drop = temp); /*Would work as the temp variable*/
temp= 2*balance;/*just for example*/
/*use the temp in further calculations*/
run;
A somewhat different take:
data want;
set have;
UI_DUM = input(compress(Prod_Desc,,"kd"),best.);
UI_DUM_last2 = mod(UI_DUM,100);
run;
You could do that all in one line of course as well. This uses the numeric modulo function to simply give you the last 2 digits (any number modulo 100 will return the final 2 digits).

Is Excel's FALSE like infinity?

Why does =FALSE<10000000000 evaluate as FALSE and =FALSE>10000000000 evaluate as TRUE? I have tried some different numbers and this seems to always be the case.
This is by design. Search help for "Troubleshoot Sort" to see the default sort order.
In an ascending sort, Microsoft Excel uses the following order.
Numbers: Numbers are sorted from the smallest negative number to the largest positive number.
Alphanumeric sort: When you sort alphanumeric text, Excel sorts left to right, character by character. For example, if a cell contains the text "A100," Excel places the cell after a cell that contains the entry "A1" and before a cell that contains the entry "A11."
Text and text that includes numbers are sorted in the following order:
0 1 2 3 4 5 6 7 8 9 (space) ! " # $ % & ( ) * , . / : ; ? # [ \ ] ^ _ ` { | } ~ + < = > A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
Apostrophes (') and hyphens (-) are ignored, with one exception: If two text strings are the same except for a hyphen, the text with the hyphen is sorted last.
Logical values: In logical values, FALSE is placed before TRUE.
Error values: All error values are equal.
Blanks: Blanks are always placed last.
The default sort order matters because that is how Excel was designed to compare different data types. Logical values are always after text and numbers. Error values are always after that. Blanks are always last. When you use comparison operators (<, <=, =, etc.) it uses the same comparison algorithm as the sort (or more likely, the sort alogrithm uses the comparison operator code, which makes them identical).
TRUE<>1 according to the sort order, but --TRUE=1. The formula parser recognized that you're trying to negate something. If it's a Boolean value, it converts it to 0 or 1. There's nothing 0-ish or 1-ish about the Boolean value, it's just the result of an internal Type Coercion function. If you type --"SomeString" it does the same thing. It sends the string into the Type Coercion function that reports back 'Unable to coerce' and ends up as #VALUE! in the cell.
That's the 'Why it behaves that way' answer. I don't know the 'Why did they design it that way' answer.
Obviously the boolean TRUE/FALSE are different data types to numbers. Check this (http://msdn.microsoft.com/en-us/library/office/bb687869.aspx) to see that boolean variables are stored in 2-byte (or whatever a short integer is for a certain architecture). However this is the memory where the data is stored, because excel actually has a special data class for boolean vars. Specifically: xltypeNum for numbers, xltypeStr for strings, and xltypeBool for what we discuss.
The relations between same types is clear, now what TRUE<1000 does?? probably nothing meaningful-useful.
Ways to overcome this issue:
=ABS(BOOLEAN_VAR), i.e. =ABS(FALSE) --> 0 and =ABS(TRUE) --> 1
or
=INT(BOOLEAN_VAR), i.e. =INT(FALSE) --> 0 and =INT(TRUE) --> 1
or
=BOOLEAN_VAR*1, i.e. =FALSE*1 --> 0 and =TRUE*1 --> 1
or
=+BOOLEAN_VAR, i.e. =+FALSE --> 0 and =+TRUE --> 1
As you see in these ways you force excel to output a numeric type of data, either by providing the boolean into a function or using the boolean var in an expression.

Resources