Div(H) and Eval(H) gives different results - rpgle

I am using data from the same files in two different programs. I tried to get the same results in my new program using an Eval(H) instead of two operations of MULT and DIV(H)
Here are the variable types :
Var1,Var3,Var4,Var5 : 9P 2
Var2 : 9P 4
Original code :
C Var1 MULT Var2 Var3
C Var3 DIV(H) Var4 Var5
In my new program, I instead tried this :
C Eval(H) Var5 = (Var1 * Var2) / Var4
But there's a .01 difference, i.e. : In the first method Var5 = 4.20 where in the second method Var5 = 4.19.
Any idea how I could correct the second method using only the Eval(H)?

Without the actual values, it's a bit difficult to illustrate but you're likely running into issues with RPG's default precision rules and the fact you've moved from an explicitly defined intermediate results (ie. Var3) to an implicitly defined one.
With the implicitly defined intermediate results, the precision and scale of (Var 1 * Var2) would be 18P6 vs the 4P2 you defined Var3 at.
The "natural" precision and scale the entire statement is something like 63P44 (assuming I did my math right).
Try
eval(h) var5 = %dec((var1 * Var2):9:2) / var4;
To force the intermediate results back to the 9P2 you had with MULT & DIV

When you use DIV, you define the lengths of any intermediate variables (like VAR3). When you use EVAL, the compiler has to store those intermediate values (such as VAR1 * VAR2) somewhere, and it internally defines the length. The RPG Reference manual describes the rules the compiler uses to calculate intermediate results precision. IBM i 7.2 > Programming > ILE languages > RPG > ILE RPG Reference > Operations, Expressions, and Functions > Expressions > Precision Rules for Numeric Operations.

Related

Looking for Python 3.x syntax - to assign a value to a variable versus binding a variable to another variable

var1 = 1
var2 = var1 # why doesn't this bind the two variables?
var2 = var2 + 3
print(var1)
print(var2)
The output is
1
4
What is the Python 3.x (added after StackrunnethOver's original answer - apologies for not specifying) syntax to bind var2 to the same memory as var1? Not that I want to, but rather that I want to make sure that my assignment statements aren't accidentally binding two variables to one another.
This line of questioning (how do I know what happens to variables and when) is usually very language-dependent, so it’s often a lot more relevant to talk about it in the context of a specific language. However, in the example you present, I think there is a general answer:
For the code:
var1 = 1
var2 = var1
var2 = var2 + 3
On line 2, there are two things that could happen:
var2 gets assigned the value 1
var2 now points to the same location in memory as var1, and var1’s location in memory holds the value 1
If #1 happens, we get the behavior you see above. This should not be surprising.
If #2 happens, now var1 and var2 point to the same location in memory. Your question is why isn’t this the case? Consider, if line 2 does make var2 point to the same thing as var1, what does line 3 do?
...
If x = y makes x point to the thing y points to, what does x = y + 3 do? Make x point to the thing y + 3 points to? This doesn’t really make sense.
What this gets at, underneath, is the difference between a value, a variable, and a pointer. In the example you give, var1 and var2 are variables, which on the left hand side of an equals sign are treated as such (you can assign values to your variables e.g. x = 3). But on the right-hand side of an equals sign, variables become their values before other operations take place. In var2 = var1 + 3, the expression becomes var2 = 1 + 3 and then var2 = 4.
In some languages, this behavior is not always automatic. Instead, you have to create it for yourself, by using pointers. This effectively means you have one way of referencing a variable x which explicitly says you want the location in memory x points to, which is the true “value of x”, and another way of referencing it x’ which explicitly says you want the value at that location in memory.
In such a world, your code could be written as
var1’ = 1
var2’ = var1’
var2’ = var2’ + 3
To get behavior #1 above, or
var1’ = 1
var2 = var1
var2’ = var2’ + 3
To get output
4
4
All this assuming that var1 and var2 have been initialized beforehand.
In such languages (like C) you can actually do things like `x = y + 3’, where x and y are pointers. It literally makes x equal to the position in memory three spots further along than y. This is called pointer arithmetic.

Rcpp: continued fractions and precision [duplicate]

How come that in the following snippet
int a = 7;
int b = 3;
double c = 0;
c = a / b;
c ends up having the value 2, rather than 2.3333, as one would expect. If a and b are doubles, the answer does turn to 2.333. But surely because c already is a double it should have worked with integers?
So how come int/int=double doesn't work?
This is because you are using the integer division version of operator/, which takes 2 ints and returns an int. In order to use the double version, which returns a double, at least one of the ints must be explicitly casted to a double.
c = a/(double)b;
Here it is:
a) Dividing two ints performs integer division always. So the result of a/b in your case can only be an int.
If you want to keep a and b as ints, yet divide them fully, you must cast at least one of them to double: (double)a/b or a/(double)b or (double)a/(double)b.
b) c is a double, so it can accept an int value on assignement: the int is automatically converted to double and assigned to c.
c) Remember that on assignement, the expression to the right of = is computed first (according to rule (a) above, and without regard of the variable to the left of =) and then assigned to the variable to the left of = (according to (b) above). I believe this completes the picture.
With very few exceptions (I can only think of one), C++ determines the
entire meaning of an expression (or sub-expression) from the expression
itself. What you do with the results of the expression doesn't matter.
In your case, in the expression a / b, there's not a double in
sight; everything is int. So the compiler uses integer division.
Only once it has the result does it consider what to do with it, and
convert it to double.
When you divide two integers, the result will be an integer, irrespective of the fact that you store it in a double.
c is a double variable, but the value being assigned to it is an int value because it results from the division of two ints, which gives you "integer division" (dropping the remainder). So what happens in the line c=a/b is
a/b is evaluated, creating a temporary of type int
the value of the temporary is assigned to c after conversion to type double.
The value of a/b is determined without reference to its context (assignment to double).
In C++ language the result of the subexpresison is never affected by the surrounding context (with some rare exceptions). This is one of the principles that the language carefully follows. The expression c = a / b contains of an independent subexpression a / b, which is interpreted independently from anything outside that subexpression. The language does not care that you later will assign the result to a double. a / b is an integer division. Anything else does not matter. You will see this principle followed in many corners of the language specification. That's juts how C++ (and C) works.
One example of an exception I mentioned above is the function pointer assignment/initialization in situations with function overloading
void foo(int);
void foo(double);
void (*p)(double) = &foo; // automatically selects `foo(fouble)`
This is one context where the left-hand side of an assignment/initialization affects the behavior of the right-hand side. (Also, reference-to-array initialization prevents array type decay, which is another example of similar behavior.) In all other cases the right-hand side completely ignores the left-hand side.
The / operator can be used for integer division or floating point division. You're giving it two integer operands, so it's doing integer division and then the result is being stored in a double.
This is technically a language-dependent, but almost all languages treat this subject the same. When there is a type mismatch between two data types in an expression, most languages will try to cast the data on one side of the = to match the data on the other side according to a set of predefined rules.
When dividing two numbers of the same type (integers, doubles, etc.) the result will always be of the same type (so 'int/int' will always result in int).
In this case you have
double var = integer result
which casts the integer result to a double after the calculation in which case the fractional data is already lost. (most languages will do this casting to prevent type inaccuracies without raising an exception or error).
If you'd like to keep the result as a double you're going to want to create a situation where you have
double var = double result
The easiest way to do that is to force the expression on the right side of an equation to cast to double:
c = a/(double)b
Division between an integer and a double will result in casting the integer to the double (note that when doing maths, the compiler will often "upcast" to the most specific data type this is to prevent data loss).
After the upcast, a will wind up as a double and now you have division between two doubles. This will create the desired division and assignment.
AGAIN, please note that this is language specific (and can even be compiler specific), however almost all languages (certainly all the ones I can think of off the top of my head) treat this example identically.
For the same reasons above, you'll have to convert one of 'a' or 'b' to a double type. Another way of doing it is to use:
double c = (a+0.0)/b;
The numerator is (implicitly) converted to a double because we have added a double to it, namely 0.0.
The important thing is one of the elements of calculation be a float-double type. Then to get a double result you need to cast this element like shown below:
c = static_cast<double>(a) / b;
or
c = a / static_cast(b);
Or you can create it directly::
c = 7.0 / 3;
Note that one of elements of calculation must have the '.0' to indicate a division of a float-double type by an integer. Otherwise, despite the c variable be a double, the result will be zero too (an integer).

Is there a programming language which allows the redefinition of numbers?

My first stab at this problem was in C
#define 2 5
assert(2+2 == 10);
Unfortunately
error: macro name must be an identifier
I also tried Scheme
(define 2 5)
but
can't define a non-symbol: (define 2 5)
I was wondering if there are any programming languages where this is possible.
I sincerely hope not.
But that said, I do know of a way in Java: you can use reflection to adjust the values of the cached boxed Integers: a JVM must cache all values in the range -128 to +127, and there does exist a mechanism to adjust the numeric values in that cache!
See https://codegolf.stackexchange.com/questions/28786/write-a-program-that-makes-2-2-5/28818#28818 for more details. Here's the code in full:
import java.lang.reflect.Field;
public class Main {
public static void main(String[] args) throws Exception {
Class cache = Integer.class.getDeclaredClasses()[0];
Field c = cache.getDeclaredField("cache");
c.setAccessible(true);
Integer[] array = (Integer[]) c.get(cache);
array[132] = array[133];
System.out.printf("%d", 2 + 2);
}
}
The output is 5, essentially achieved by redefining the number 4.
I remembered hearing a story about this long ago, and today I decided to follow-up on it. That follow-up lead me to this question which unfortunately isn't exactly answered. This isn't exactly an answer, either, but ... here ya go.
I believe this can be done with early Fortran compilers.
From that post (which is a copy of an original post to comp.lang.python which I haven't been able to track-down):
> subroutine munge (i)
> i = 3
> return
>and then in your main program did:
> j = 7
> call munge (7)
> write (6, 11) j
> 11 format ('j = ', i6)
>it would print 3!
The reason seems to be due to a combination of:
Constant interning
Fortran's pass-by-reference semantics
The compiler interns the constant value (7) and then calls the munge function with a pointer to the interned "constant" 7. The munge function changes the value of the passed-by-reference integer value and so now the interned constant value is 3.
So, this won't universally change the value of 7 to 3 across the whole program, but anywhere that interned "constant" value is used will now be using 3 as its numeric value.
This can be extraordinarily surprising (and rightly so, IMO) to younger programmers who have only dealt with languages whose arguments are almost always passed by value (unless otherwise specified). C, C++, C#, Erlang, Java, javascript, Perl, Python, Ruby, etc. all use pass-by-value. For those languages, pass-by-reference semantics are achieved either using encapsulation (e.g. passing a mutable complex type such as an object) or explicitly passing a pointer to a value instead of the value (e.g. using the & operator in C and similar languages).

Thrust custom binary predicate parallelization

I am implementing a custom binary predicate used by the thrust::max_element search algorithm. It also keeps track of a value of interest which the algorithm alone cannot yield. It looks something like this:
struct cmp_class{
cmp_class(int *val1){
this->val1 = val1;
}
bool operator()(int i, int j){
if (j < *val1) { *val1 = j; }
return i < j;
}
int *val1;
};
int val1 = ARRAY[0];
std::max_element(ARRAY, ARRAY+length, cmp(&val1));
.... use val1
My actual binary predicate is quite a bit more complex, but the example above captures the gist of it: I am passing a pointer to an integer to the binary predicate cmp, which then writes to that integer to keep track of some value (here the running minimum). Since max_element first calls cmp()(ARRAY[0],ARRAY[1]) and then cmp()(running maximum,ARRAY[i]), I only look at value j inside cmp and therefore initialize val1 = ARRAY[0] to ensure ARRAY[0] is taken into account.
If I do the above on the host, using std::max_element for example, this works fine. The values of val1 is what I expect given known data. However, using Thrust to execute this on the GPU, its value is off. I suspect this is due to the parallelization of thrust::max_element, which is recursively applied on sub arrays, the results of which form another array which thrust::max_element is run on, etc. Does this hold water?
In general, the binary predicates used for thrust reductions are expected to be commutative. I'm using "commutative" here to mean that the predicate result should be valid regardless of the order in which the arguments are presented.
At the initial stage of a thrust parallel reduction, the arguments are likely to be presented in an order you might expect (i.e. in the order of the vectors passed to the reduce function, or in the order that the values occur in a single vector.) However, later on in the parallel reduction process, the origin of the arguments may get mixed up, during the parallel-sweeping. Any binary comparison functor that assumes an ordering to the arguments is probably broken, for thrust parallel reductions.
In your case, the boolean result of your comparison functor should be valid regardless of the order of arguments presented, and in that respect it appears to be properly commutative.
However, regarding the custom storage functionality you have built-in around val1, it seems pretty clear that the results in val1 could be different depending on the order in which arguments are passed to the functor. Consider this simple max-finding sequence amongst a set values passed to the functor as (i,j) (assume val1 starts out at a large value):
values: 10 5 3 7 12
comparison pairs: (10,5) (10,3) (10,7) (10,12)
comparison result: 10 10 10 12
val1 storage: 5 3 3 3
Now suppose that we simply reverse the order that arguments are presented to the functor:
values: 10 5 3 7 12
comparison pairs: (5,10) (3,10) (7,10) (12,10)
comparison result: 10 10 10 12
val1 storage: 10 10 10 10
Another issue is that you have no atomic protection on val1 that I can see:
if (j < *val1) { *val1 = j; }
The above line of code may be OK in a serial realization. In a parallel multi-threaded algorithm, you have the possibility for multiple threads to be accessing (reading and writing) *val1 simultaneously, which will have undefined results.

Behavior of `=` in alloy fact

I was experimenting with alloy and wrote this code.
one sig s1{
vals: some Int
}{
#vals = 4
}
one sig s2{
vals: some Int
}{
#vals = 4
}
fact {
all a : s1.vals | a > 2
all i : s2.vals | i < 15
s1.vals = s2.vals
}
pred p{}
run p
It seems to me that {3,4,5,6} at least is a solution however Alloy says no instance found. When I comment s1.vals = s2.vals or change i < 15 to i > 2, it finds instances.
Can anyone please explain me why? Thanks.
Alloy's relationship with integers is sometimes mildly strained; it's not designed for heavily numeric applications, and many uses of integers in conventional programming are better handled in Alloy by other signatures.
The default bit width for integers is 4 bits, and Alloy uses twos-complement integers, so your run p is asking for a world in which integers range in value from -8 to 7. In that world, the constraint i < 15 is subject to integer overflow, and turns out to mean, in effect, i < -1. (To see this, comment out both of your constraints so that you get some instances. Then (a) leaf through the instances produced by the Analylzer and look at the integers that appear in them; you'll see their range is as I describe. Also, (b) open the Evaluator and type the numeral "15"; you'll see that its value in this universe is -1.)
If you change your run command to provide an appropriate bit width for integers (e.g. run p for 5 int), you'll get instances which are probably more like what you were expecting.
An alternative change, however, which leads to a more idiomatic Alloy model, is to abstract away from the specific kind of value by defining a sig for values:
sig value {}
Then change the declaration for vals in s1 and s2 from some Int to some value, and comment out the numeric constraints on them (or substitute some other interesting constraints for them). And then run p in a suitable scope (e.g. run p for 8 value).

Resources