File indexing completed on 2024-10-04 22:54:37
0001 #pragma GCC diagnostic ignored "-Wformat"
0002 #include <iostream>
0003 #include <cmath>
0004 #include <cstdlib>
0005 #include <cstdio>
0006
0007 namespace almostEqualDetail {
0008 union fasi {
0009 int i;
0010 float f;
0011 };
0012
0013 union dasi {
0014 long long i;
0015 double f;
0016 };
0017
0018 }
0019
0020 inline int intDiff(float a, float b) {
0021 using namespace almostEqualDetail;
0022
0023
0024 fasi fa;
0025 fa.f = a;
0026
0027 if (fa.i < 0)
0028 fa.i = 0x80000000 - fa.i;
0029
0030 fasi fb;
0031 fb.f = b;
0032 if (fb.i < 0)
0033 fb.i = 0x80000000 - fb.i;
0034 return std::abs(fa.i - fb.i);
0035 }
0036
0037 inline long long intDiff(double a, double b) {
0038 using namespace almostEqualDetail;
0039 dasi fa;
0040 fa.f = a;
0041
0042 if (fa.i < 0)
0043 fa.i = 0x8000000000000000LL - fa.i;
0044
0045 dasi fb;
0046 fb.f = b;
0047 if (fb.i < 0)
0048 fb.i = 0x8000000000000000LL - fb.i;
0049 return std::abs(fa.i - fb.i);
0050 }
0051
0052 template <typename T>
0053 inline bool almostEqual(T a, T b, int maxUlps) {
0054
0055
0056
0057 return intDiff(a, b) <= maxUlps;
0058 }
0059
0060 namespace {
0061 template <typename T>
0062 inline T eta(T x, T y, T z) {
0063 T t(z / std::sqrt(x * x + y * y));
0064 return std::log(t + std::sqrt(t * t + T(1)));
0065 }
0066 template <typename T>
0067 inline T eta2(T x, T y, T z) {
0068 T t = (z * z) / (x * x + y * y);
0069 return copysign(std::log(std::sqrt(t) + std::sqrt(t + T(1))), z);
0070 }
0071
0072 inline float eta3(float x, float y, float z) {
0073 float t(z / std::sqrt(x * x + y * y));
0074 return ::asinhf(t);
0075 }
0076 inline double eta3(double x, double y, double z) {
0077 double t(z / std::sqrt(x * x + y * y));
0078 return ::asinh(t);
0079 }
0080
0081 void look(float x) {
0082 int e;
0083 float r = ::frexpf(x, &e);
0084 std::cout << x << " exp " << e << " res " << r << std::endl;
0085
0086 union {
0087 float val;
0088 int bin;
0089 } f;
0090
0091 f.val = x;
0092 printf("%e %a %x\n", f.val, f.val, f.bin);
0093
0094 int log_2 = ((f.bin >> 23) & 255) - 127;
0095 f.bin &= 0x7FFFFF;
0096
0097 std::cout << "exp " << log_2 << " mant in binary " << std::hex << f.bin << " mant as float " << std::dec
0098 << (f.bin | 0x800000) * ::pow(2., -23) << std::endl
0099 << std::endl;
0100 }
0101
0102 void look(double x) {
0103
0104
0105
0106
0107 union {
0108 double val;
0109 long long bin;
0110 } f;
0111
0112 f.val = x;
0113
0114 printf("%e %a %x\n", f.val, f.val, f.bin);
0115
0116 }
0117
0118 }
0119
0120 void peta() {
0121 std::cout << "T t(z/std::sqrt(x*x+y*y)); return std::log(t+std::sqrt(t*t+T(1)));" << std::endl;
0122 {
0123 float xn = 122.436f, yn = 10.7118f, zn = -1115.f;
0124 float etan = eta(xn, yn, zn);
0125
0126 std::cout << etan << std::endl;
0127 look(etan);
0128 std::cout << -etan << std::endl;
0129 look(-etan);
0130
0131 float xp = 122.436f, yp = 10.7118f, zp = 1115.f;
0132 float etap = eta(xp, yp, zp);
0133
0134 std::cout << etap << std::endl;
0135 look(etap);
0136
0137 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0138 }
0139
0140 {
0141 double xn = 122.436, yn = 10.7118, zn = -1115.;
0142 double etan = eta(xn, yn, zn);
0143
0144 std::cout << etan << std::endl;
0145 look(etan);
0146 std::cout << -etan << std::endl;
0147 look(-etan);
0148
0149 double xp = 122.436, yp = 10.7118, zp = 1115.;
0150 double etap = eta(xp, yp, zp);
0151
0152 std::cout << etap << std::endl;
0153 look(etap);
0154
0155 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0156 }
0157 }
0158
0159 void peta2() {
0160 std::cout << "T t = (z*z)/(x*x+y*y); return copysign(std::log(std::sqrt(t)+std::sqrt(t+T(1))), z);" << std::endl;
0161 {
0162 float xn = 122.436f, yn = 10.7118f, zn = -1115.f;
0163 float etan = eta2(xn, yn, zn);
0164
0165 std::cout << etan << std::endl;
0166 look(etan);
0167 std::cout << -etan << std::endl;
0168 look(-etan);
0169
0170 float xp = 122.436f, yp = 10.7118f, zp = 1115.f;
0171 float etap = eta2(xp, yp, zp);
0172
0173 std::cout << etap << std::endl;
0174 look(etap);
0175
0176 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0177 }
0178
0179 {
0180 double xn = 122.436, yn = 10.7118, zn = -1115.;
0181 double etan = eta2(xn, yn, zn);
0182
0183 std::cout << etan << std::endl;
0184 look(etan);
0185 std::cout << -etan << std::endl;
0186 look(-etan);
0187
0188 double xp = 122.436, yp = 10.7118, zp = 1115.;
0189 double etap = eta2(xp, yp, zp);
0190
0191 std::cout << etap << std::endl;
0192 look(etap);
0193
0194 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0195 }
0196 }
0197
0198 void peta3() {
0199 std::cout << "t(z/std::sqrt(x*x+y*y)); return ::asinh(t);" << std::endl;
0200 {
0201 float xn = 122.436f, yn = 10.7118f, zn = -1115.f;
0202 float etan = eta3(xn, yn, zn);
0203
0204 std::cout << etan << std::endl;
0205 look(etan);
0206 std::cout << -etan << std::endl;
0207 look(-etan);
0208
0209 float xp = 122.436f, yp = 10.7118f, zp = 1115.f;
0210 float etap = eta3(xp, yp, zp);
0211
0212 std::cout << etap << std::endl;
0213 look(etap);
0214
0215 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0216 }
0217
0218 {
0219 double xn = 122.436, yn = 10.7118, zn = -1115.;
0220 double etan = eta3(xn, yn, zn);
0221
0222 std::cout << etan << std::endl;
0223 look(etan);
0224 std::cout << -etan << std::endl;
0225 look(-etan);
0226
0227 double xp = 122.436, yp = 10.7118, zp = 1115.;
0228 double etap = eta3(xp, yp, zp);
0229
0230 std::cout << etap << std::endl;
0231 look(etap);
0232
0233 std::cout << intDiff(etap, -etan) << std::endl << std::endl;
0234 }
0235 }
0236
0237 int main() {
0238 peta();
0239 peta2();
0240 peta3();
0241
0242 return 0;
0243 }