8000 Branch-free sign-extension · python/cpython@994703e · GitHub
[go: up one dir, main page]

Skip to content

Commit 994703e

Browse files
committed
Branch-free sign-extension
1 parent 204e924 commit 994703e

File tree

1 file changed

+16
-12
lines changed

1 file changed

+16
-12
lines changed

Modules/_struct.c

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -817,8 +817,9 @@ bu_short(_structmodulestate *state, const char *p, const formatdef *f)
817817
do {
818818
x = (x<<8) | *bytes++;
819819
} while (--i > 0);
820-
/* Extend sign. */
821-
return PyLong_FromLong(x & 0x8000U ? (long)x - 0x10000 : (long)x);
820+
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
821+
x = (x ^ 0x8000U) - 0x8000U;
822+
return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x): (long)x);
822823
}
823824

824825
static PyObject *
@@ -834,8 +835,8 @@ bu_int(_structmodulestate *state, const char *p, const formatdef *f)
834835
x = (x<<8) | *bytes++;
835836
} while (--i > 0);
836837
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
837-
return PyLong_FromLong(x & 0x80000000U ?
838-
-1 - (long)(0xFFFFFFFFU - x) : (long)x);
838+
x = (x ^ 0x80000000U) - 0x80000000U;
839+
return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x): (long)x);
839840
}
840841

841842
static PyObject *
@@ -863,8 +864,9 @@ bu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
863864
x = (x<<8) | *bytes++;
864865
} while (--i > 0);
865866
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
866-
return PyLong_FromLongLong(x & 0x8000000000000000U ?
867-
-1 - (long long)(0xFFFFFFFFFFFFFFFFU - x) : (long long)x);
867+
x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
868+
return PyLong_FromLongLong(
869+
x & 0x8000000000000000U ? -1 - (long long)(~x): (long long)x);
868870
}
869871

870872
static PyObject *
@@ -1058,8 +1060,9 @@ lu_short(_structmodulestate *state, const char *p, const formatdef *f)
10581060
do {
10591061
x = (x<<8) | bytes[--i];
10601062
} while (i > 0);
1061-
/* Extend sign. */
1062-
return PyLong_FromLong(x & 0x8000U ? (long)x - 0x10000 : (long)x);
1063+
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
1064+
x = (x ^ 0x8000U) - 0x8000U;
1065+
return PyLong_FromLong(x & 0x8000U ? -1 - (long)(~x): (long)x);
10631066
}
10641067

10651068
static PyObject *
@@ -1075,8 +1078,8 @@ lu_int(_structmodulestate *state, const char *p, const formatdef *f)
10751078
x = (x<<8) | bytes[--i];
10761079
} while (i > 0);
10771080
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
1078-
return PyLong_FromLong(x & 0x80000000U ?
1079-
-1 - (long)(0xFFFFFFFFU - x) : (long)x);
1081+
x = (x ^ 0x80000000U) - 0x80000000U;
1082+
return PyLong_FromLong(x & 0x80000000U ? -1 - (long)(~x): (long)x);
10801083
}
10811084

10821085
static PyObject *
@@ -1104,8 +1107,9 @@ lu_longlong(_structmodulestate *state, const char *p, const formatdef *f)
11041107
x = (x<<8) | bytes[--i];
11051108
} while (i > 0);
11061109
/* Extend sign, avoiding implementation-defined or undefined behaviour. */
1107-
return PyLong_FromLongLong(x & 0x8000000000000000U ?
1108-
-1 - (long long)(0xFFFFFFFFFFFFFFFFU - x) : (long long)x);
1110+
x = (x ^ 0x8000000000000000U) - 0x8000000000000000U;
1111+
return PyLong_FromLongLong(
1112+
x & 0x8000000000000000U ? -1 - (long long)(~x): (long long)x);
11091113
}
11101114

11111115
static PyObject *

0 commit comments

Comments
 (0)
0