Skip to content

Instantly share code, notes, and snippets.

@minoki
Created June 1, 2020 11:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save minoki/0e4ebcee49d540ede29f26a0025903ca to your computer and use it in GitHub Desktop.
Save minoki/0e4ebcee49d540ede29f26a0025903ca to your computer and use it in GitHub Desktop.
ABC169 C問題のコーナーケースを生成するやつ
#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