if(b<0 || 0x10ffff<b) { // combine(list, b) requires a valid code point b
return U_SENTINEL;
}
+#if U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
return combine(list, b)>>1;
+#else
+ int32_t compositeAndFwd=combine(list, b);
+ return compositeAndFwd>=0 ? compositeAndFwd>>1 : U_SENTINEL;
+#endif
}
// Very similar to composeQuickCheck(): Make the same changes in both places if relevant.
#include "unicode/utypes.h"
#include "unicode/putil.h"
+/**
+ * \def U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
+ * Nearly all CPUs and compilers implement a right-shift of a signed integer
+ * as an Arithmetic Shift Right which copies the sign bit (the Most Significant Bit (MSB))
+ * into the vacated bits (sign extension).
+ * For example, (int32_t)0xfff5fff3>>4 becomes 0xffff5fff and -1>>1=-1.
+ *
+ * This can be useful for storing a signed value in the upper bits
+ * and another bit field in the lower bits.
+ * The signed value can be retrieved by simple right-shifting.
+ *
+ * This is consistent with the Java language.
+ *
+ * However, the C standard allows compilers to implement a right-shift of a signed integer
+ * as a Logical Shift Right which copies a 0 into the vacated bits.
+ * For example, (int32_t)0xfff5fff3>>4 becomes 0x0fff5fff and -1>>1=0x7fffffff.
+ *
+ * Code that depends on the natural behavior should be guarded with this macro,
+ * with an alternate path for unusual platforms.
+ * @internal
+ */
+#ifdef U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC
+ /* Use the predefined value. */
+#else
+ /*
+ * Nearly all CPUs & compilers implement a right-shift of a signed integer
+ * as an Arithmetic Shift Right (with sign extension).
+ */
+# define U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC 1
+#endif
+
/** Define this to 1 if your platform supports IEEE 754 floating point,
to 0 if it does not. */
#ifndef IEEE_754
#include "uinvchar.h"
#include <stdio.h>
+/* See the comments on U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC. */
+static void TestSignedRightShiftIsArithmetic() {
+ int32_t x=0xfff5fff3;
+ int32_t m=-1;
+ int32_t x4=x>>4;
+ int32_t m1=m>>1;
+ UBool signedRightShiftIsArithmetic= x4==0xffff5fff && m1==-1;
+ if(signedRightShiftIsArithmetic==U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC) {
+ log_info("signed right shift is Arithmetic Shift Right: %d\n",
+ signedRightShiftIsArithmetic);
+ } else {
+ log_err("error: unexpected signed right shift is Arithmetic Shift Right: %d\n"
+ " You need to change the value of U_SIGNED_RIGHT_SHIFT_IS_ARITHMETIC "
+ "for your platform.\n",
+ signedRightShiftIsArithmetic);
+ }
+}
static UBool compareWithNAN(double x, double y);
static void doAssert(double expect, double got, const char *message);
char versionString[17]; /* xxx.xxx.xxx.xxx\0 */
UChar versionUString[] = { 0x0031, 0x002E, 0x0030, 0x002E,
0x0032, 0x002E, 0x0038, 0x0000 }; /* 1.0.2.8 */
- UBool isModified = FALSE;
UVersionInfo version;
UErrorCode status = U_ZERO_ERROR;
static void addToolUtilTests(TestNode** root) {
addTest(root, &toolutil_findBasename, "putiltst/toolutil/findBasename");
addTest(root, &toolutil_findDirname, "putiltst/toolutil/findDirname");
+ addTest(root, &TestSignedRightShiftIsArithmetic, "putiltst/toolutil/TestSignedRightShiftIsArithmetic");
/*
Not yet tested: