On my 6.2 OpenBSD

europa: [/usr/src/usr.bin/awk]
[1270]>> uname -a
OpenBSD europa.undisclosed.noname 6.2 GENERIC.MP#134 amd64

europa: [/usr/src/usr.bin/awk]
[1271]>> echo "172" | awk '{ print lshift($0, 24); }'
-1409286144

this seems to be caused by typecasting getfval in run.c to signed integer.

Applying the following fix

cvs server: Diffing .
Index: run.c
===================================================================
RCS file: /cvs/src/usr.bin/awk/run.c,v
retrieving revision 1.40
diff -u -p -r1.40 run.c
--- run.c       16 Dec 2015 19:44:42 -0000      1.40
+++ run.c       6 Jan 2018 08:45:54 -0000
@@ -1561,7 +1561,7 @@ Cell *bltin(Node **a, int n)      /* builtin
                        break;
                }
                y = execute(a[1]->nnext);
-               u = ((int)getfval(x)) << ((int)getfval(y));
+               u = ((u_int32_t)getfval(x)) << ((u_int32_t)getfval(y));
                tempfree(y);
                nextarg = nextarg->nnext;
                break;

this produces the correct result, u is defined as Awkfloat, which is
typedef to double.

europa: [/usr/src/usr.bin/awk]
[1282]>> echo "172" | ./awk '{ print lshift($0, 24); }'
2885681152

europa: [/usr/src/usr.bin/awk]
[1283]>> md5 ./awk
MD5 (./awk) = 58bca671f685dd106826cacc8ec71f67

europa: [/usr/src/usr.bin/awk]
[1284]>> md5 /usr/bin/awk
MD5 (/usr/bin/awk) = fb82ce48dc8a1e37f36d067befe5a8ce

Is the reason to have the typecast set to max signed integer value?
FYI, my test ubuntu, which is not awk, but gawk, also produces the correct
result.
May I send the fix for typecast set to u_int32_t if the above diff is
kosher?

Thanks,
Prabhu
-

Reply via email to