The inline-declared variable is not recognized - abap

I am having a problem where the system does not recognize a local variable that I have declared. The code is as follows:
DATA(lv_dmbtr) = ZSD_LGS-DMBTR.
IF ( lv_dmbtr MOD 10000000 ) LE 9.
lv_dmbtr / 10000000 = lv_tenmillions. //Error line
lv_tenmillions_check = lv_tenmillions MOD 1.
IF lv_tenmillions_check > 0.
"Convert
ENDIF.
IF lv_tenmillions_check < 0.
"ZERO
ENDIF.
ENDIF.
The program gives me an error in the line that I have input in the program, where it says "There is no LV_DMBTR statement. Please check the spelling."
May anyone of you know where the problem may be?
Thank you all in advance!

The line
lv_dmbtr / 10000000 = lv_tenmillions.
is indeed not syntactically correct. I am as confused by that line as the ABAP interpreter. So I am not sure what exactly you are trying to accomplish with it. But I would guess that it seems to be some kind of assignment of a computation to some variable. In an assignment, the variable you assign to is always on the left of the = sign, while the expression which creates the value is on the right of the = sign.
So having a mathematical formula on the left-hand side of an equal sign makes no sense.
Either you are trying to say "lv_tenmillion shall be lv_dmbtr divided by 10000000". In that case the correct line would be
lv_tenmillions = lv_dmbtr / 10000000.
Or you are trying to say "one millionth of lv_dmbtr shall be equal to lv_tenmillion" which would be equivalent to saying "lv_dmbtr shall be equal to lv_tenmillion multiplied by 10000000" or
lv_dmbtr = lv_tenmillions * 10000000.

Try this:
DATA(lv_dmbtr) = ZSD_LGS-DMBTR.
lv_dmbtr = ZSD_LGS-DMBTR MOD 10000000
IF lv_dmbtr MOD 10000000 LE 9.
lv_dmbtr / 10000000 = lv_tenmillions. //Error line
lv_tenmillions_check = lv_tenmillions MOD 1.
IF lv_tenmillions_check > 0.
"Convert
ENDIF.
IF lv_tenmillions_check < 0.
"ZERO
ENDIF.
ENDIF.

Related

Why does ABAP round a number down to the nearest integer when using the REDUCE operator?

In the code below, lv_sum_openamount should be 3.45 but the program rounds the number as 3.
I want lv_sum_openamount as 3.
How can I do that ?
DATA(lv_sum_openamount) = REDUCE dmbtr_cs( INIT sum = 0 FOR wa_amnt IN <fs_comp> NEXT sum += wa_amnt-open_amount.
LOOP AT <fs_comp> ASSIGNING <fs_comp_alv>.
TRY.
<fs_comp_alv>-pull_amount = ( <fs_pack>-reamount / lv_sum_openamount ) * <fs_comp_alv>-open_amount.
CATCH cx_sy_zerodivide.
<fs_comp_alv>-pull_amount = 0.
ENDTRY.
ENDLOOP.
The culprit is the part INIT sum = 0.
0 is an integer, so the type for sum gets automatically derived as an integer. That means that the REDUCE-loop then uses integer arithmetic, so its output is rounded down.
Try INIT sum = CONV dmbtr_cs( 0 ) instead. This will convert the literal of 0 to the type you need and in turn force sum to also get that type.

Rounding while comparing N variable with number. How to avoid?

Hello to every one and HAPPY NEW YEAR.
I have the following problem: a char field contains an amount and I want to make the following check: if wfile-dmbtr < 0.00
The code I use:
data: lv_dmbtr(18) type n.
write wfile-dmbtr to lv_dmbtr.
replace first occurrence of '.' in lv_dmbtr with ''.
translate lv_dmbtr using ',.'.
if lv_dmbtr <= '0.00'.
The problem is for values between 0.01 to 0.49, and the program most probably round them to 0 and returns True.
The dmbtr amounts have the following mask: 12.235,99. Does anyone knows how to overcome this issue?
Thanks in advance.
Elias
Elias. Happy new year to you too.
Type N does not allow the use of decimals (even though you might be able to see it in the debugger if you force such value). That's the reason why the number is being rounded and the condition evaluation 'seems' to fail.
In addition, after you do the number conversion / formatting, you might be better off using a decimal type variable to do the condition evaluation (such as type of data element MAXBT).
Example:
DATA: lv_dmbtr(18) TYPE c, " Used to be type N instead of pure CHAR.
lv_aux TYPE maxbt.
WRITE '0,01' TO lv_dmbtr.
REPLACE FIRST OCCURRENCE OF '.' IN lv_dmbtr WITH ''.
TRANSLATE lv_dmbtr USING ',.'.
CONDENSE lv_dmbtr.
lv_aux = lv_dmbtr.
IF lv_aux <= '0.00'.
BREAK-POINT.
ELSE.
BREAK-POINT. " It should enter this bracket for the value 0,01
ENDIF.
Hope it helps.

Round to Integer in Smalltalk

I am currently building my first stuff on Smalltalk and I have hit an issue. I have to deal with a user-entered number, and I need to div it by 2 and still be an integer. If an user inputs 10, I will work with 5, if they input 11, I have to work with 6, but I will obviously get 5.5.
If I could get the mod of a number I could simply make sure mod = 0 else add 0.5 and it would do just as good, but I just can't find how to make a mod operation in SmallTalk, all my searches end up in unrelated stuff about actual social smalltalk, which is extremely frustrating.
So if you could tell me how to get the mod of a number it would be great, if you could tell me how to round up with a separate function, even better. Thanks for your help and time beforehand.
UPDATE: After some research, I tried to do it this way:
mod := par rem: 2.
mod = 0 ifFalse: [ par := par + 0.5 ].
where as "mod" is mod of the variable "par", and if it isn't 0, it should add up 0.5 to par.
My issue now is that trying to use par in a timesRepeat brings up a "BoxedFloat64 did not understand #timesRepeat" error. So I am still in the same issue, or just need a way to make a float into an integer.
There are a lot of ways. For example
Add 1 to entered number before div by 2 if entered number is odd
temp := enteredNumber.
temp odd ifTrue: [temp := temp + 1 ].
^temp / 2
Using ceiling method
^(enteredNumber / 2) ceiling
In Smalltalk, we have an operator for integer division (and even two operators):
11 / 2
would answer a Fraction, not a whole Integer
But:
11 // 2
would answer the quotient of division, rounded toward negative infinity
And the corresponding remainder will be:
11 \\ 2
The second operator quo: for quotient and rem: for remainder
The difference is only with negative receiver/operand: the later ones are truncating the quotient toward zero.
-11 // 4 = -3. "floored toward negative infinity"
-11 \\ 4 = 1.
(-11 quo: 4) = -2. "truncated toward zero"
(-11 rem: 4) = -3.
If you want to round the quotient upper (toward positive infinity), then you can write:
(anInteger + 1) // 2.
Or same without parenthesis if you are confident enough in binary operator precedence:
anInteger + 1 // 2.

Verilog question mark (?) operator

I'm trying to translate a Verilog program into VHDL and have stumbled across a statement where a question mark (?) operator is used in the Verilog program.
The following is the Verilog code;
1 module music(clk, speaker);
2 input clk;
3 output speaker;
4 parameter clkdivider = 25000000/440/2;
5 reg [23:0] tone;
6 always #(posedge clk) tone <= tone+1;
7 reg [14:0] counter;
8 always #(posedge clk) if(counter==0) counter <= (tone[23] ? clkdivider-1 : clkdivider/2-1); else counter <= counter-1;
9 reg speaker;
10 always #(posedge clk) if(counter==0) speaker <= ~speaker;
11 endmodule
I don't understand the 8th line, could anyone please shed some light on this?
I've read on the asic-world website that the question mark is the Verilog alternate for the Z character. But I don't understand why it's being used in this context.
Kind regards
That's a ternary operator. It's shorthand for an if statement
Format:
condition ? if true : if false
Example:
tone[23] ? clkdivider-1 : clkdivider/2-1
Translates to something like (not correct syntax but I think you'll get it):
if tone[23] is 1, counter = clkdivider-1
else counter = clkdivider/2-1
Here are two examples of a 2 to 1 MUX using if statement and ternary operator.
On the asic-world website, it is covered under Conditional Operators
Another way of writing, e.g. the following Verilog:
q <= tone[23] ? clkdivider-1 : clkdivider/2-1;
in VHDL would be:
q <= clkdivider-1 when tone[23] else clkdivider/2-1;
Think of it as a MUX, before the ? is the selection bit and on two sides of : are the inputs

Weird Objective-C Mod Behavior for Negative Numbers

So I thought that negative numbers, when mod'ed should be put into positive space... I cant get this to happen in objective-c
I expect this:
-1 % 3 = 2
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
But get this
-1 % 3 = -1
0 % 3 = 0
1 % 3 = 1
2 % 3 = 2
Why is this and is there a workaround?
result = n % 3;
if( result < 0 ) result += 3;
Don't perform extra mod operations as suggested in the other answers. They are very expensive and unnecessary.
In C and Objective-C, the division and modulus operators perform truncation towards zero. a / b is floor(a / b) if a / b > 0, otherwise it is ceiling(a / b) if a / b < 0. It is always the case that a == (a / b) * b + (a % b), unless of course b is 0. As a consequence, positive % positive == positive, positive % negative == positive, negative % positive == negative, and negative % negative == negative (you can work out the logic for all 4 cases, although it's a little tricky).
If n has a limited range, then you can get the result you want simply by adding a known constant multiple of 3 that is greater that the absolute value of the minimum.
For example, if n is limited to -1000..2000, then you can use the expression:
result = (n+1002) % 3;
Make sure the maximum plus your constant will not overflow when summed.
We have a problem of language:
math-er-says: i take this number plus that number mod other-number
code-er-hears: I add two numbers and then devide the result by other-number
code-er-says: what about negative numbers?
math-er-says: WHAT? fields mod other-number don't have a concept of negative numbers?
code-er-says: field what? ...
the math person in this conversations is talking about doing math in a circular number line. If you subtract off the bottom you wrap around to the top.
the code person is talking about an operator that calculates remainder.
In this case you want the mathematician's mod operator and have the remainder function at your disposal. you can convert the remainder operator into the mathematician's mod operator by checking to see if you fell of the bottom each time you do subtraction.
If this will be the behavior, and you know that it will be, then for m % n = r, just use r = n + r. If you're unsure of what will happen here, use then r = r % n.
Edit: To sum up, use r = ( n + ( m % n ) ) % n
I would have expected a positive number, as well, but I found this, from ISO/IEC 14882:2003 : Programming languages -- C++, 5.6.4 (found in the Wikipedia article on the modulus operation):
The binary % operator yields the remainder from the division of the first expression by the second. .... If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined
JavaScript does this, too. I've been caught by it a couple times. Think of it as a reflection around zero rather than a continuation.
Why: because that is the way the mod operator is specified in the C-standard (Remember that Objective-C is an extension of C). It confuses most people I know (like me) because it is surprising and you have to remember it.
As to a workaround: I would use uncleo's.
UncleO's answer is probably more robust, but if you want to do it on a single line, and you're certain the negative value will not be more negative than a single iteration of the mod (for example if you're only ever subtracting at most the mod value at any time) you can simplify it to a single expression:
int result = (n + 3) % 3;
Since you're doing the mod anyway, adding 3 to the initial value has no effect unless n is negative (but not less than -3) in which case it causes result to be the expected positive modulus.
There are two choices for the remainder, and the sign depends on the language. ANSI C chooses the sign of the dividend. I would suspect this is why you see Objective-C doing so also. See the wikipedia entry as well.
Not only java script, almost all the languages shows the wrong answer'
what coneybeare said is correct, when we have mode'd we have to get remainder
Remainder is nothing but which remains after division and it should be a positive integer....
If you check the number line you can understand that
I also face the same issue in VB and and it made me to forcefully add extra check like
if the result is a negative we have to add the divisor to the result
Instead of a%b
Use: a-b*floor((float)a/(float)b)
You're expecting remainder and are using modulo. In math they are the same thing, in C they are different. GNU-C has Rem() and Mod(), objective-c only has mod() so you will have to use the code above to simulate rem function (which is the same as mod in the math world, but not in the programming world [for most languages at least])
Also note you could define an easy to use macro for this.
#define rem(a,b) ((int)(a-b*floor((float)a/(float)b)))
Then you could just use rem(-1,3) in your code and it should work fine.