On 22-Aug-2016 20:22 -0700, Vernon Hamberg wrote:
On 8/22/2016 8:58 PM, CRPence wrote:
[…]
For example, (0x555F<=0x777D)=True with a purely /hex/ comparison,
but when those values are to be represented by data-type
DECIMAL(3), the comparison no longer holds true; i.e.
(555<=-777)=False.
The arguments do not have to all be the same sign - one of the tests
compared negative and positive […] Same data type, including length
and precision, OK.
I realize the above comment was already explained by John as
incorrect, but I figured I would point to my final comment in my prior
message [quoted above], and address similarly, the specific test-case of
the "min() procedure" that was presented\used in the message:
[
http://archive.midrange.com/rpg400-l/201608/msg00238.html]
"…
dcl-s Packed1 packed(5 : 0);
dcl-s Packed2 packed(5 : 0);
…
Packed1 = 4;
Packed2 = -2;
ptr = min(%addr(Packed1) : %addr(Packed2));
…"
That code establishes that (0x00002D<=0x00004F), which is of course
*true*, and _seemingly confirms_ that the decimal expression (-2<=4) is
also *true*; all seems right in the world. However, simply negate each
of those arguments, and now the min() procedure will establish that
(0x00002F<=0x00004D), which is of course also *true*, yet also
_seemingly confirms_ that the decimal expression (2<=-4) which clearly
is *false*; thus giving a proof by counter-example, that a claim that
the procedure can function properly across signed Packed Binary Coded
Decimal (BCD) numeric values must be false.
The same problem exists with signed Zoned BCD as well as signed
Integer. That is because every value, while "well ordered" in the
traditional sense of decimal digits, the internal binary representations
of those decimal values are not similarly well-ordered; i.e. every
increase\decrease in the decimal value is not always represented as *a
respective* increase\decrease to the binary value. Negative packed BCD
are well-ordered, despite inversely so, because every decrease in the
decimal value is always represented by a like-increase in the binary
value; thus they can be compared against each other. Positive packed
BCD are well-ordered, to most, intuitively so, because every increase in
the decimal value is always represented by a like-increase in the binary
value; thus they can be compared against each other.
How about some positive ideas about whether it is possible? I don't
know - would operational descriptors do anything worthwhile?
OPDESC are surely too lacking to be useful in that regard; though
Mark implied he would likely be able to cover many scenarios with just
that information being available. I already had suggested Data Pointers
as a possibility [in response to the mention of OPDESC]:
[
http://archive.midrange.com/rpg400-l/201608/msg00216.html]
"… their use probably would enable a much better means to code a generic
procedure to do the work of MIN or MAX, than would OPDESC; and there is
support for both FLOAT and INTEGER. …"
What are the restrictions, if any, of the typical min() or max()
function in languages like C/C++? I think I saw something to the
effect that both arguments have to be of the same type - which would
often be some kind of integer.
I find C code somewhat nauseating, nor do I really recall what is
available even though I recall seeing examples :-)
A lot of min/max stuff in C++ seem to be implemented as macros
- no such animal, is there, in RPG? Side effects are mentioned.
While any language would benefit programmers by having a /statement/
that could perform a native-form of MIN or MAX, a robust macro language
could enable expanding native code to implement the capability; a macro
language could be available as part of a compiler [as with C\CPP], or
written separately as a pre-processor, much like what the SQL
pre-compiler does.
For example, to implement the proposed:
fld=%max(value1: value2);
for which the RPG code implementing that feature might be written as:
fld = value1;
if fld < value2;
fld = value2;
endif;
a macro invocation [denoted here with a question mark, and terminated
with a semicolon] might be coded as shown below. The effect of that
macro would be the generation of the above if\endif logic; all that is
needed is passed as arguments on the macro, and the macro naming just
identifies its purpose:
?MAXmacro( fld, value1 , value2 );
An alternative macro might generate a procedure declaration that
perhaps is as-specific-as having named a data-type and size, perhaps
with the procedure algorithmically named according to that data
type\size; the RPG programmer codes the procedure invocation knowing the
effects for the generated code, plus codes the macro invocation that
would generate the procedure:
…
fld = MAXof05P00Values( value1 : value2 ) ;
…
// subprocedures follow:
?genMAXproc( "packed(5:0)" , maxargs(2) ) ;
Such a macro need only generate a consistent procedure prototype for
whatever data-type\size was input, for both return-value and [the proper
number of] arguments; the logic for the comparisons would be /written/
just once, in an effective include [as-modified by the macro language to
replace the type\size specifications] or fully generated within the
macro language. The actual code [though not the parameters] could be
composed such that operations perform irrespective\agnostic of the data
type. The code then could be generated anywhere that such a procedure
is required to be expanded. Perhaps not as nice as either the proposed
/void/ typing from the OP or the later-proposed BIFs, but the capability
would be quite powerful nonetheless, and not limited in applicability to
just those potential capabilities.
This was not presented as a final solution - maybe someone else will
see value here and run with it - a very generic, type-safe pair of
functions <<SNIP>>
I could present some RPG source that could be used as a basis for a
methodology to dynamically generate a MAX [or MIN] procedure that would
accommodate a specific data type\size; effectively using the idea of
/include member(s) that would be modified, similar to how the above
alludes to a macro language effecting such a revision or full-write of
the procedure.
Effectively, the concept would be that if I want a MAX procedure for
the program I am coding, I could just code in my program an assignment
like myRtnVal15P05=MaxOfPACKED_15_05(myPgmVar01:myPgmVar02); for which
the myPgmVar## are all of type PACKED(15:5), as is the conspicuously
named variable to which the result is assigned. Then I could issue a
request such as the imaginary command below that would ask to Generate
An RPG MAX Procedure source, and perhaps additionally perform actions
such as storing the /generated/ source, creating a module from that
source, perhaps even add the module to a service program that would
stores all of these unique MAX procedures and deal somehow with the
condition of already-exists.?:
GENRPGMAXP
DATATYPE(*PACKED 15 5) /* proc: MaxOfPACKED_15_05 */
MAXARGS(256) /* 2 rqd args, 254 *NOPASS args */
SRCFILE() /* *NONE or named to rqs a cpy */
MODULE() /* *NONE or named to CrtRpgmMod */
As an Amazon Associate we earn from qualifying purchases.