Created
June 1, 2020 11:06
-
-
Save minoki/0e4ebcee49d540ede29f26a0025903ca to your computer and use it in GitHub Desktop.
ABC169 C問題のコーナーケースを生成するやつ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <stdbool.h> | |
#include <string.h> | |
#include <math.h> | |
#include <float.h> | |
#include <inttypes.h> | |
#if defined(TEST_FLOAT128) | |
// For _Float128 type, see TS 18661-3 | |
// For _Float128 support on GCC, see https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html#Floating-Types | |
#include <quadmath.h> // quadmath_snprintf | |
#endif | |
int64_t ac(int64_t a, int y) | |
{ | |
return a * y / INT64_C(100); | |
} | |
int64_t wa1(int64_t x, int y) | |
{ | |
double a = (double)x; | |
double b = (double)y / 100.0; | |
return (int64_t)floor(a * b); | |
} | |
int64_t wa1ld(int64_t x, int y) | |
{ | |
long double a = (long double)x; | |
long double b = (long double)y / 100.0L; | |
return (int64_t)floorl(a * b); | |
} | |
#if defined(TEST_FLOAT128) | |
int64_t wa1q(int64_t x, int y) | |
{ | |
_Float128 a = (_Float128)x; | |
_Float128 b = (_Float128)y / 100.0F128; | |
return (int64_t)floorq(a * b); | |
} | |
#endif | |
int64_t wa2(int64_t a, int y) | |
{ | |
double b = (double)y / 100.0; | |
int b2 = (int)(b * 100.0); | |
return a * (int64_t)b2 / INT64_C(100); | |
} | |
int64_t wa2ld(int64_t a, int y) | |
{ | |
long double b = (long double)y / 100.0L; | |
int b2 = (int)(b * 100.0L); | |
return a * (int64_t)b2 / INT64_C(100); | |
} | |
#if defined(TEST_FLOAT128) | |
int64_t wa2q(int64_t a, int y) | |
{ | |
_Float128 b = (_Float128)y / 100.0F128; | |
int b2 = (int)(b * 100.0F128); | |
return a * (int64_t)b2 / INT64_C(100); | |
} | |
#endif | |
int64_t wa3(int64_t a, int y) | |
{ | |
double b = (double)y / 100.0; | |
int b2 = (int)(b * 1000.0); | |
return (int64_t)(a * (uint64_t)b2 / UINT64_C(1000)); | |
} | |
int64_t wa3ld(int64_t a, int y) | |
{ | |
long double b = (long double)y / 100.0L; | |
int b2 = (int)(b * 1000.0L); | |
return (int64_t)(a * (uint64_t)b2 / UINT64_C(1000)); | |
} | |
#if defined(TEST_FLOAT128) | |
int64_t wa3q(int64_t a, int y) | |
{ | |
_Float128 b = (_Float128)y / 100.0F128; | |
int b2 = (int)(b * 1000.0F128); | |
return (int64_t)(a * (uint64_t)b2 / UINT64_C(1000)); | |
} | |
#endif | |
int main(int argc, char *argv[]) | |
{ | |
printf("double (precision: %d bits; approx. %d digits in decimal)\n", LDBL_MANT_DIG, LDBL_DIG); | |
printf("long double (precision: %d bits; approx. %d digits in decimal)\n", LDBL_MANT_DIG, LDBL_DIG); | |
#if defined(TEST_FLOAT128) | |
printf("float128 (precision: %d bits; approx. %d digits in decimal)\n", FLT128_MANT_DIG, FLT128_DIG); | |
#endif | |
int max = 999; | |
const int64_t i64_1e15 = INT64_C(1000000000000000); | |
for (int64_t a = i64_1e15 - INT64_C(10); a <= i64_1e15; ++a) { | |
for (int y = 0; y < 1000; ++y) { | |
int64_t result = ac(a, y); | |
int64_t r_wa1 = wa1(a, y); | |
int64_t r_wa1ld = wa1ld(a, y); | |
int64_t r_wa2 = wa2(a, y); | |
int64_t r_wa2ld = wa2ld(a, y); | |
int64_t r_wa3 = wa3(a, y); | |
int64_t r_wa3ld = wa3ld(a, y); | |
int b = (r_wa1 != result) + (r_wa1ld != result) + (r_wa2 != result) + (r_wa2ld != result) + (r_wa3 != result) + (r_wa3ld != result); | |
#if defined(TEST_FLOAT128) | |
int64_t r_wa1q = wa1q(a, y); | |
int64_t r_wa2q = wa2q(a, y); | |
int64_t r_wa3q = wa3q(a, y); | |
b += (r_wa1q != result) + (r_wa2q != result) + (r_wa3q != result); | |
#endif | |
if (b > 0 && b <= 4) { | |
printf("%" PRIi64 " %.2f\n", a, (double)y / 100.0); | |
printf("Expected: %" PRIi64 "\n", result); | |
if (r_wa1 != result) { | |
printf("WA1: %" PRIi64 "\n", r_wa1); | |
} | |
if (r_wa1ld != result) { | |
printf("WA1LD: %" PRIi64 "\n", r_wa1ld); | |
} | |
#if defined(TEST_FLOAT128) | |
if (r_wa1q != result) { | |
printf("WA1Q: %" PRIi64 "\n", r_wa1q); | |
} | |
#endif | |
if (r_wa2 != result) { | |
printf("WA2: %" PRIi64 "\n", r_wa2); | |
} | |
if (r_wa2ld != result) { | |
printf("WA2LD: %" PRIi64 "\n", r_wa2ld); | |
} | |
#if defined(TEST_FLOAT128) | |
if (r_wa2q != result) { | |
printf("WA2Q: %" PRIi64 "\n", r_wa2q); | |
} | |
#endif | |
if (r_wa3 != result) { | |
printf("WA3: %" PRIi64 "\n", r_wa3); | |
} | |
if (r_wa3ld != result) { | |
printf("WA3LD: %" PRIi64 "\n", r_wa3ld); | |
} | |
#if defined(TEST_FLOAT128) | |
if (r_wa3q != result) { | |
printf("WA3Q: %" PRIi64 "\n", r_wa3q); | |
} | |
#endif | |
if (r_wa1 != result || r_wa2 != result || r_wa3 != result) { | |
double b = (double)y / 100.0; | |
double c = b * 100.0; | |
double d = b * 1000.0; | |
printf("(double)B = %.25g (%a)\n", b, b); | |
printf("(double)B * 100.0 = %.25g (%a)\n", c, c); | |
printf("(double)B * 1000.0 = %.25g (%a)\n", d, d); | |
} | |
if (r_wa1ld != result || r_wa2ld != result || r_wa3ld != result) { | |
long double b = (long double)y / 100.0L; | |
long double c = b * 100.0L; | |
long double d = b * 1000.0L; | |
printf("(long double)B = %.25Lg (%La)\n", b, b); | |
printf("(long double)B * 100.0 = %.25Lg (%La)\n", c, c); | |
printf("(long double)B * 1000.0 = %.25Lg (%La)\n", d, d); | |
} | |
#if defined(TEST_FLOAT128) | |
if (r_wa1q != result || r_wa2q != result) { | |
_Float128 b = (_Float128)y / 100.0F128; | |
_Float128 c = b * 100.0F128; | |
char gbuf[128], abuf[128]; | |
quadmath_snprintf(gbuf, sizeof(gbuf), "%.40Qg", b); | |
quadmath_snprintf(abuf, sizeof(abuf), "%Qa", b); | |
printf("(float128)B = %s (%s)\n", gbuf, abuf); | |
quadmath_snprintf(gbuf, sizeof(gbuf), "%.40Qg", c); | |
quadmath_snprintf(abuf, sizeof(abuf), "%Qa", c); | |
printf("(float128)B * 100.0 = %s (%s)\n", gbuf, abuf); | |
} | |
#endif | |
puts("---"); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment