This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix inaccuracy of clog, clog10 near |z| = 1 (bug 13629)


This patch fixes the remaining cases of bug 13629, clog and clog10
inaccurate near |z| = 1.  In these cases it is necessary to compute
x^2 + y^2 - 1 accurately, without large errors from cancellation; the
final value may be on the order of epsilon^2 (for epsilon =
FLT_EPSILON, DBL_EPSILON or LDBL_EPSILON as appropriate).  This is
implemented through helper functions such as __x2y2m1 to compute this
expression using Dekker's algorithms for precision extension in
intermediate calculations.  (The case of IBM long double, where the
underlying type is not an IEEE floating-point type with basic
operations accurate to 0.5ulp, is more complicated, and the
calculations there are done directly with double, producing a
collection of 12 double values that need adding to produce a long
double value with small error in this final addition, where the other
cases only need to add four values.)

Tested x86_64 and x86.  Also did spot tests for mips64 and powerpc to
verify the ldbl-128 and ldbl-128ibm implementations do work with small
ulps.  (The powerpc testing shows some large ulps for clog but those
are for pre-existing tests and for the imaginary part of the result
whereas this patch is only about the real part; they appear to be a
pre-existing issue resulting from a bug in atan2l, which I've filed as
bug 14610.)

(The helper functions may also be of use in improving the accuracy of
catan / catanh in certain cases where intermediate calculations
involve 1 - x^2 - y^2, although I haven't yet worked out exactly what
cases those functions need improving in to avoid excess inaccuracy /
overflow / underflow.)

2012-09-24  Joseph Myers  <joseph@codesourcery.com>

	[BZ #13629]
	* math/s_clog.c (__clog): Handle more values close to |z| = 1
	specially.
	* math/s_clog10.c (__clog10): Likewise.
	* math/s_clog10f.c (__clog10f): Likewise.
	* math/s_clog10l.c (__clog10l): Likewise.
	* math/s_clogf.c (__clogf): Likewise.
	* math/s_clogl.c (__clogl): Likewise.
	* math/Makefile (libm-calls): Add x2y2m1.
	* sysdeps/generic/math_private.h (__x2y2m1f): Declare.
	(__x2y2m1): Likewise.
	(__x2y2m1l): Likewise.
	* sysdeps/ieee754/dbl-64/x2y2m1.c: New file.
	* sysdeps/ieee754/dbl-64/x2y2m1f.c: Likewise.
	* sysdeps/ieee754/ldbl-128/x2y2m1l.c: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c: Likewise.
	* sysdeps/ieee754/ldbl-96/x2y2m1.c: Likewise.
	* sysdeps/ieee754/ldbl-96/x2y2m1l.c: Likewise.
	* math/libm-test.inc (clog_test, clog10_test): Add more tests.
	* sysdeps/i386/fpu/libm-test-ulps: Update.
	* sysdeps/x86_64/fpu/libm-test-ulps: Likewise.

diff --git a/math/Makefile b/math/Makefile
index 60e3899..7759873 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -58,7 +58,7 @@ libm-calls = e_acos e_acosh e_asin e_atan2 e_atanh e_cosh e_exp e_fmod	\
 	     s_catan s_casin s_ccos s_csin s_ctan s_ctanh s_cacos	\
 	     s_casinh s_cacosh s_catanh s_csqrt s_cpow s_cproj s_clog10 \
 	     s_fma s_lrint s_llrint s_lround s_llround e_exp10 w_log2	\
-	     s_isinf_ns $(calls:s_%=m_%)
+	     s_isinf_ns $(calls:s_%=m_%) x2y2m1
 
 include ../Makeconfig
 
diff --git a/math/libm-test.inc b/math/libm-test.inc
index fa781fc..e8398bd 100644
--- a/math/libm-test.inc
+++ b/math/libm-test.inc
@@ -2495,6 +2495,66 @@ clog_test (void)
   TEST_c_c (clog, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 9.868649107778739752403260515979017248596e-19L, 1.061846605795612822522063052130030717368e-301L);
 #endif
 
+  TEST_c_c (clog, 0x0.ffffffp0L, 0x0.ffffffp-100L, -5.960464655174753498633255797994360530379e-8L, 7.888609052210118054117285652827862296732e-31L);
+#ifndef TEST_FLOAT
+  TEST_c_c (clog, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -1.110223024625156602053389888482372171810e-16L, 9.332636185032188789900895447238171696171e-302L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+  TEST_c_c (clog, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -5.421010862427522170184200798202494495630e-20L, 3.548665303440282824232502561095699343814e-4516L);
+#endif
+
+  TEST_c_c (clog, 0x1a6p-10L, 0x3a5p-10L, -1.4305135209763571252847059962654228661815e-06L, 1.1460277178115757370775644871674016684074L);
+  TEST_c_c (clog, 0xf2p-10L, 0x3e3p-10L, 6.1988446308070710970664736815277450078106e-06L, 1.3322126499153926210226335249558203898460L);
+  TEST_c_c (clog, 0x4d4ep-15L, 0x6605p-15L, -1.6298145321400412054744424587143483169412e-08L, 0.9223574537155056772124552172295398141249L);
+  TEST_c_c (clog, 0x2818p-15L, 0x798fp-15L, 1.5366822245016167178749091974664853785194e-08L, 1.2522014929038946066987318471922169174157L);
+  TEST_c_c (clog, 0x9b57bp-20L, 0xcb7b4p-20L, -3.9563019528687610863490232935890272740908e-11L, 0.9187593477446338910857133065497364950682L);
+  TEST_c_c (clog, 0x2731p-20L, 0xfffd0p-20L, 4.4110493034041283943115971658295280288115e-11L, 1.5612279663766352262688735061954290528838L);
+  TEST_c_c (clog, 0x2ede88p-23L, 0x771c3fp-23L, -4.4764192352906350039050902870893173560494e-13L, 1.1959106857549200806818600493552847793381L);
+  TEST_c_c (clog, 0x11682p-23L, 0x7ffed1p-23L, 1.1723955140027907954461000991619077811832e-12L, 1.5622968405332756349813737986164832897108L);
+  TEST_c_c (clog, 0xa1f2c1p-24L, 0xc643aep-24L, -1.0480505352462576151523512837107080269981e-13L, 0.8858771987699967480545613322309315260313L);
+  TEST_c_c (clog, 0x659feap-24L, 0xeaf6f9p-24L, 3.7303493627403868207597214252239749960738e-14L, 1.1625816408046866464773042283673653469061L);
+#ifndef TEST_FLOAT
+  TEST_c_c (clog, 0x4447d7175p-35L, 0x6c445e00ap-35L, -1.4823076576950255933915367361099865652625e-20L, 1.0081311552703893116404606212158840190615L);
+  TEST_c_c (clog, 0x2dd46725bp-35L, 0x7783a1284p-35L, 4.4469229730850767799109418892826021157328e-20L, 1.2046235979300843056806465045930070146351L);
+  TEST_c_c (clog, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -3.0292258760486853327810377824479932031744e-26L, 0.7998237934177411746093524982030330293980L);
+  TEST_c_c (clog, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 5.3718272201930019901317065495843842735179e-26L, 1.0503831592447830576186444373011142397404L);
+  TEST_c_c (clog, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -6.2122796286154679676173624516405339768606e-30L, 1.4904138780720095276446375492434049214172L);
+  TEST_c_c (clog, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 3.2047474274603604594851472963586149973093e-29L, 1.4422922682185099608731642353544207976604L);
+  TEST_c_c (clog, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -9.7375017988218644730510244778042114638107e-30L, 0.9790637929494922564724108399524154766631L);
+  TEST_c_c (clog, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 8.3076914081087805757422664530653247447136e-30L, 1.2072712126771536614482822173033535043206L);
+  TEST_c_c (clog, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -2.5083311595699359750201056724289010648701e-30L, 1.3710185432462268491534742969536240564640L);
+  TEST_c_c (clog, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 1.0168910106364605304135563536838075568606e-30L, 0.8208373755522359859870890246475340086663L);
+  TEST_c_c (clog, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 5.0844550531823026520677817684239496041087e-32L, 1.2627468605458094918919206628466016525397L);
+  TEST_c_c (clog, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -5.2000108498455368032511404449795741611813e-32L, 1.5288921536982513453421343495466824420259L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+  TEST_c_c (clog, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -1.1931267660846218205882675852805793644095e-36L, 1.2402109774337032400594953899784058127412L);
+  TEST_c_c (clog, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 6.4064442119814669184296141278612389400075e-37L, 0.9193591364645830864185131402313014890145L);
+  TEST_c_c (clog, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -2.3362950222592964220878638677292132852104e-37L, 1.1856121127236268105413184264288408265852L);
+  TEST_c_c (clog, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 2.4244570985709679851855191080208817099132e-37L, 1.1393074519572050614551047548718495655972L);
+  TEST_c_c (clog, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -9.9182335850630508484862145328126979066934e-39L, 1.3146479888794807046338799047003947008804L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+  TEST_c_c (clog, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -1.0509738482436128031927971874674370984602e-45L, 1.0509191467640012308402149909370784281448L);
+  TEST_c_c (clog, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 1.3487497719126364307640897239165442763573e-43L, 1.1750493008528425228929764149024375035382L);
+  TEST_c_c (clog, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -4.7775669192897997174762089350332738583822e-50L, 0.8393953487996880419413728440067635213372L);
+  TEST_c_c (clog, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 2.8398125044729578740243199963484494962411e-50L, 0.9149964976334130461795060758257083099706L);
+  TEST_c_c (clog, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -3.5048022044913950094635368750889659723004e-57L, 1.3345633256521815205858155673950177421079L);
+  TEST_c_c (clog, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 4.1101771307217268747345114262406964584250e-56L, 1.4596065864518742494094402406719567059585L);
+  TEST_c_c (clog, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -1.4281333889622737316199756373421183559948e-62L, 1.3673546561165378090903506783353927980633L);
+  TEST_c_c (clog, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 1.0027319539522347477331743836657426754857e-62L, 0.8193464073721167323313606647411269414759L);
+  TEST_c_c (clog, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -1.7471844652198029695350765775994001163767e-63L, 1.1789110097072986038243729592318526094314L);
+  TEST_c_c (clog, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 4.3299788920664682288477984749202524623248e-63L, 1.4746938237585656250866370987773473745867L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+  TEST_c_c (clog, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -1.1683999374665377365054966073875064467108e-66L, 1.3257197596350832748781065387304444940172L);
+  TEST_c_c (clog, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 1.5077923002544367932999503838191154621839e-65L, 1.2897445708311412721399861948957141824914L);
+  TEST_c_c (clog, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -7.1865869169568789348552370692485515571497e-67L, 0.8730167479365994646287897223471819363668L);
+  TEST_c_c (clog, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 6.6255694866654064502633121109394710807528e-66L, 1.0526409614996288387567810726095850312049L);
+  TEST_c_c (clog, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 4.6017338806965821566734340588575402712716e-67L, 1.3547418904611758959096647942223384691728L);
+  TEST_c_c (clog, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 2.5993421227864195179698176012564317527271e-67L, 1.4132318089683022770487383611430906982461L);
+#endif
+
   END (clog, complex);
 }
 
@@ -2655,6 +2715,66 @@ clog10_test (void)
   TEST_c_c (clog10, 0x1.00000000000000123456789abcp0L, 0x1.23456789p-1000L, 4.285899851347756186652871946325962330640e-19L, 4.611541215247321502041995872887317363241e-302L);
 #endif
 
+  TEST_c_c (clog10, 0x0.ffffffp0L, 0x0.ffffffp-100L, -2.588596909321764128428416045209904492216e-8L, 3.425979381266895667295625489912064603415e-31L);
+#ifndef TEST_FLOAT
+  TEST_c_c (clog10, 0x0.fffffffffffff8p0L, 0x0.fffffffffffff8p-1000L, -4.821637332766435821255375046554377090472e-17L, 4.053112396770095089737411317782466262176e-302L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MIN_EXP <= -16381
+  TEST_c_c (clog10, 0x0.ffffffffffffffffp0L, 0x0.ffffffffffffffffp-15000L, -2.354315103889861110220423157644627849164e-20L, 1.541165759405643564697852372112893034397e-4516L);
+#endif
+
+  TEST_c_c (clog10, 0x1a6p-10L, 0x3a5p-10L, -6.2126412844802358329771948751248003038444e-07L, 0.4977135139537443711784513409096950995985L);
+  TEST_c_c (clog10, 0xf2p-10L, 0x3e3p-10L, 2.6921240173351112953324592659528481616879e-06L, 0.5785726025799636431142862788413361783862L);
+  TEST_c_c (clog10, 0x4d4ep-15L, 0x6605p-15L, -7.0781945783414996953799915941870192015212e-09L, 0.4005747524909781155537088181659175147564L);
+  TEST_c_c (clog10, 0x2818p-15L, 0x798fp-15L, 6.6737261053986614395049481326819059203910e-09L, 0.5438241985991753781478398141908629586460L);
+  TEST_c_c (clog10, 0x9b57bp-20L, 0xcb7b4p-20L, -1.7182001068739620267773842120965071561416e-11L, 0.3990121149225253562859800593935899629087L);
+  TEST_c_c (clog10, 0x2731p-20L, 0xfffd0p-20L, 1.9156943718715958194239364991329064049438e-11L, 0.6780326907904082601285090019969008967595L);
+  TEST_c_c (clog10, 0x2ede88p-23L, 0x771c3fp-23L, -1.9440841725722970687903291200493082253766e-13L, 0.5193774116724956222518530053006822210323L);
+  TEST_c_c (clog10, 0x11682p-23L, 0x7ffed1p-23L, 5.0916490233953865181284669870035717560498e-13L, 0.6784968969384861816694467029319146542069L);
+  TEST_c_c (clog10, 0xa1f2c1p-24L, 0xc643aep-24L, -4.5516256421319921959681423447271490869664e-14L, 0.3847315790697197749315054516562206543710L);
+  TEST_c_c (clog10, 0x659feap-24L, 0xeaf6f9p-24L, 1.6200701438094619117335617123525612051457e-14L, 0.5049027913635038013499728086604870749732L);
+#ifndef TEST_FLOAT
+  TEST_c_c (clog10, 0x4447d7175p-35L, 0x6c445e00ap-35L, -6.4375803621988389731799033530075237868110e-21L, 0.4378257977686804492768642780897650927167L);
+  TEST_c_c (clog10, 0x2dd46725bp-35L, 0x7783a1284p-35L, 1.9312741086596516918394613098872836703188e-20L, 0.5231613813514771042838490538484014771862L);
+  TEST_c_c (clog10, 0x164c74eea876p-45L, 0x16f393482f77p-45L, -1.3155760824064879362415202279780039150764e-26L, 0.3473590599762514228227328130640352044313L);
+  TEST_c_c (clog10, 0xfe961079616p-45L, 0x1bc37e09e6d1p-45L, 2.3329549194675052736016290082882121135546e-26L, 0.4561756099441139182878993697611751382976L);
+  TEST_c_c (clog10, 0xa4722f19346cp-51L, 0x7f9631c5e7f07p-51L, -2.6979587627476803379953050733225113494503e-30L, 0.6472785229986997177606324374555347813105L);
+  TEST_c_c (clog10, 0x10673dd0f2481p-51L, 0x7ef1d17cefbd2p-51L, 1.3918041236396763648388478552321724382899e-29L, 0.6263795733790237053262025311642907438291L);
+  TEST_c_c (clog10, 0x8ecbf810c4ae6p-52L, 0xd479468b09a37p-52L, -4.2289432987513243393180377141513840878196e-30L, 0.4252020027092323591068799049905597805296L);
+  TEST_c_c (clog10, 0x5b06b680ea2ccp-52L, 0xef452b965da9fp-52L, 3.6079845358966994996207055940336690133424e-30L, 0.5243112258263349992771652393178033846555L);
+  TEST_c_c (clog10, 0x659b70ab7971bp-53L, 0x1f5d111e08abecp-53L, -1.0893543813872082317104059174982092534059e-30L, 0.5954257879188711495921161433751775633232L);
+  TEST_c_c (clog10, 0x15cfbd1990d1ffp-53L, 0x176a3973e09a9ap-53L, 4.4163015461643576961232672330852798804976e-31L, 0.3564851427422832755956993418877523303529L);
+  TEST_c_c (clog10, 0x1367a310575591p-54L, 0x3cfcc0a0541f60p-54L, 2.2081507730821788480616336165447731164865e-32L, 0.5484039935757001196548030312819898864760L);
+  TEST_c_c (clog10, 0x55cb6d0c83af5p-55L, 0x7fe33c0c7c4e90p-55L, -2.2583360179249556400630343805573865814771e-32L, 0.6639894257763289307423302343317622430835L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 64
+  TEST_c_c (clog10, 0x298c62cb546588a7p-63L, 0x7911b1dfcc4ecdaep-63L, -5.1816837072162316773907242302011632570857e-37L, 0.5386167838952956925896424154370364458140L);
+  TEST_c_c (clog10, 0x4d9c37e2b5cb4533p-63L, 0x65c98be2385a042ep-63L, 2.7822833698845776001753149807484078521508e-37L, 0.3992725998539071066769046272515417679815L);
+  TEST_c_c (clog10, 0x602fd5037c4792efp-64L, 0xed3e2086dcca80b8p-64L, -1.0146400362652473358437501879334790111898e-37L, 0.5149047982335273098246594109614460842099L);
+  TEST_c_c (clog10, 0x6b10b4f3520217b6p-64L, 0xe8893cbb449253a1p-64L, 1.0529283395205396881397407610630442563938e-37L, 0.4947949395762683446121140513971996916447L);
+  TEST_c_c (clog10, 0x81b7efa81fc35ad1p-65L, 0x1ef4b835f1c79d812p-65L, -4.3074341162203896332989394770760901408798e-39L, 0.5709443672155660428417571212549720987784L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 106
+  TEST_c_c (clog10, 0x3f96469050f650869c2p-75L, 0x6f16b2c9c8b05988335p-75L, -4.5643214291682663316715446865040356750881e-46L, 0.4564083863660793840592614609053162690362L);
+  TEST_c_c (clog10, 0x3157fc1d73233e580c8p-75L, 0x761b52ccd435d7c7f5fp-75L, 5.8575458340992751256451490143468457830297e-44L, 0.5103174273246635294300470585396890237265L);
+  TEST_c_c (clog10, 0x155f8afc4c48685bf63610p-85L, 0x17d0cf2652cdbeb1294e19p-85L, -2.0748709499710785084693619097712106753591e-50L, 0.3645447681189598740620098186365764884771L);
+  TEST_c_c (clog10, 0x13836d58a13448d750b4b9p-85L, 0x195ca7bc3ab4f9161edbe6p-85L, 1.2333149003324592532859843519619084433953e-50L, 0.3973779298829931059309198145608711073016L);
+  TEST_c_c (clog10, 0x1df515eb171a808b9e400266p-95L, 0x7c71eb0cd4688dfe98581c77p-95L, -1.5221162575729652613635150540947625639689e-57L, 0.5795934880811949230121092882659698986043L);
+  TEST_c_c (clog10, 0xe33f66c9542ca25cc43c867p-95L, 0x7f35a68ebd3704a43c465864p-95L, 1.7850272475173865337808494725293124613817e-56L, 0.6338990862456906754888183278564382516852L);
+  TEST_c_c (clog10, 0x6771f22c64ed551b857c128b4cp-105L, 0x1f570e7a13cc3cf2f44fd793ea1p-105L, -6.2023045024810589256360494043570293518879e-63L, 0.5938345819561308555003145899438513900776L);
+  TEST_c_c (clog10, 0x15d8ab6ed05ca514086ac3a1e84p-105L, 0x1761e480aa094c0b10b34b09ce9p-105L, 4.3548095442952115860848857519953610343042e-63L, 0.3558376234889641500775150477035448866763L);
+  TEST_c_c (clog10, 0x187190c1a334497bdbde5a95f48p-106L, 0x3b25f08062d0a095c4cfbbc338dp-106L, -7.5879257211204444302994221436282805900756e-64L, 0.5119945461708707332160859198685423099187L);
+  TEST_c_c (clog10, 0x6241ef0da53f539f02fad67dabp-106L, 0x3fb46641182f7efd9caa769dac0p-106L, 1.8804859395820231849002915747252695375405e-63L, 0.6404513901551516189871978418046651877394L);
+#endif
+#if defined TEST_LDOUBLE && LDBL_MANT_DIG >= 113
+  TEST_c_c (clog10, 0x3e1d0a105ac4ebeacd9c6952d34cp-112L, 0xf859b3d1b06d005dcbb5516d5479p-112L, -5.0742964549782184008668435276046798273476e-67L, 0.5757527761596220360985719127090110408283L);
+  TEST_c_c (clog10, 0x47017a2e36807acb1e5214b209dep-112L, 0xf5f4a550c9d75e3bb1839d865f0dp-112L, 6.5482587585671294601662599808612773010057e-66L, 0.5601289501766423782280643144987875760229L);
+  TEST_c_c (clog10, 0x148f818cb7a9258fca942ade2a0cap-113L, 0x18854a34780b8333ec53310ad7001p-113L, -3.1210950417524756037077807411854181477733e-67L, 0.3791463562379872585396164879981280044658L);
+  TEST_c_c (clog10, 0xfd95243681c055c2632286921092p-113L, 0x1bccabcd29ca2152860ec29e34ef7p-113L, 2.8774482675253468630312378575186855052697e-66L, 0.4571561610046221605554903008571429975493L);
+  TEST_c_c (clog10, 0xdb85c467ee2aadd5f425fe0f4b8dp-114L, 0x3e83162a0f95f1dcbf97dddf410eap-114L, 1.9985076315737626043096596036300177494613e-67L, 0.5883569274304683249184005177865521205198L);
+  TEST_c_c (clog10, 0x1415bcaf2105940d49a636e98ae59p-115L, 0x7e6a150adfcd1b0921d44b31f40f4p-115L, 1.1288799405048268615023706955013387413519e-67L, 0.6137587762850841972073301550420510507903L);
+#endif
+
   END (clog10, complex);
 }
 
diff --git a/math/s_clog.c b/math/s_clog.c
index 2593066..79b1f37 100644
--- a/math/s_clog.c
+++ b/math/s_clog.c
@@ -85,6 +85,19 @@ __clog (__complex__ double x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1p (d2m1) / 2.0;
 	}
+      else if (absx < 1.0
+	       && absx >= 0.75
+	       && absy < DBL_EPSILON / 2.0
+	       && scale == 0)
+	{
+	  double d2m1 = (absx - 1.0) * (absx + 1.0);
+	  __real__ result = __log1p (d2m1) / 2.0;
+	}
+      else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0)
+	{
+	  double d2m1 = __x2y2m1 (absx, absy);
+	  __real__ result = __log1p (d2m1) / 2.0;
+	}
       else
 	{
 	  double d = __ieee754_hypot (absx, absy);
diff --git a/math/s_clog10.c b/math/s_clog10.c
index ef997ee..4ccb5bc 100644
--- a/math/s_clog10.c
+++ b/math/s_clog10.c
@@ -88,6 +88,19 @@ __clog10 (__complex__ double x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
 	}
+      else if (absx < 1.0
+	       && absx >= 0.75
+	       && absy < DBL_EPSILON / 2.0
+	       && scale == 0)
+	{
+	  double d2m1 = (absx - 1.0) * (absx + 1.0);
+	  __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
+	}
+      else if (absx < 1.0 && (absx >= 0.75 || absy >= 0.5) && scale == 0)
+	{
+	  double d2m1 = __x2y2m1 (absx, absy);
+	  __real__ result = __log1p (d2m1) * (M_LOG10E / 2.0);
+	}
       else
 	{
 	  double d = __ieee754_hypot (absx, absy);
diff --git a/math/s_clog10f.c b/math/s_clog10f.c
index c61e8af..1789f1a 100644
--- a/math/s_clog10f.c
+++ b/math/s_clog10f.c
@@ -90,6 +90,19 @@ __clog10f (__complex__ float x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
 	}
+      else if (absx < 1.0f
+	       && absx >= 0.75f
+	       && absy < FLT_EPSILON / 2.0f
+	       && scale == 0)
+	{
+	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
+	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
+	}
+      else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
+	{
+	  float d2m1 = __x2y2m1f (absx, absy);
+	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
+	}
       else
 	{
 	  float d = __ieee754_hypotf (absx, absy);
diff --git a/math/s_clog10l.c b/math/s_clog10l.c
index d50f616..958f74a 100644
--- a/math/s_clog10l.c
+++ b/math/s_clog10l.c
@@ -89,6 +89,19 @@ __clog10l (__complex__ long double x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
 	}
+      else if (absx < 1.0L
+	       && absx >= 0.75L
+	       && absy < LDBL_EPSILON / 2.0L
+	       && scale == 0)
+	{
+	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
+	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
+	}
+      else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0)
+	{
+	  long double d2m1 = __x2y2m1l (absx, absy);
+	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
+	}
       else
 	{
 	  long double d = __ieee754_hypotl (absx, absy);
diff --git a/math/s_clogf.c b/math/s_clogf.c
index 92f782c..2b9038b 100644
--- a/math/s_clogf.c
+++ b/math/s_clogf.c
@@ -85,6 +85,19 @@ __clogf (__complex__ float x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1pf (d2m1) / 2.0f;
 	}
+      else if (absx < 1.0f
+	       && absx >= 0.75f
+	       && absy < FLT_EPSILON / 2.0f
+	       && scale == 0)
+	{
+	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
+	  __real__ result = __log1pf (d2m1) / 2.0f;
+	}
+      else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
+	{
+	  float d2m1 = __x2y2m1f (absx, absy);
+	  __real__ result = __log1pf (d2m1) / 2.0f;
+	}
       else
 	{
 	  float d = __ieee754_hypotf (absx, absy);
diff --git a/math/s_clogl.c b/math/s_clogl.c
index eaba572..af3ed99 100644
--- a/math/s_clogl.c
+++ b/math/s_clogl.c
@@ -85,6 +85,19 @@ __clogl (__complex__ long double x)
 	    d2m1 += absy * absy;
 	  __real__ result = __log1pl (d2m1) / 2.0L;
 	}
+      else if (absx < 1.0L
+	       && absx >= 0.75L
+	       && absy < LDBL_EPSILON / 2.0L
+	       && scale == 0)
+	{
+	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
+	  __real__ result = __log1pl (d2m1) / 2.0L;
+	}
+      else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0)
+	{
+	  long double d2m1 = __x2y2m1l (absx, absy);
+	  __real__ result = __log1pl (d2m1) / 2.0L;
+	}
       else
 	{
 	  long double d = __ieee754_hypotl (absx, absy);
diff --git a/sysdeps/generic/math_private.h b/sysdeps/generic/math_private.h
index 5267ec3..4bdbf32 100644
--- a/sysdeps/generic/math_private.h
+++ b/sysdeps/generic/math_private.h
@@ -364,6 +364,11 @@ extern double __slowexp (double __x);
 extern double __slowpow (double __x, double __y, double __z);
 extern void __docos (double __x, double __dx, double __v[]);
 
+/* Helpers for complex arithmetic.  */
+extern float __x2y2m1f (float, float);
+extern double __x2y2m1 (double, double);
+extern long double __x2y2m1l (long double, long double);
+
 #ifndef math_opt_barrier
 # define math_opt_barrier(x) \
 ({ __typeof (x) __x = (x); __asm ("" : "+m" (__x)); __x; })
diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps
index d35635c..86da780 100644
--- a/sysdeps/i386/fpu/libm-test-ulps
+++ b/sysdeps/i386/fpu/libm-test-ulps
@@ -880,6 +880,12 @@ float: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i":
+float: 1
+ifloat: 1
 Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i":
 ildouble: 1
 ldouble: 1
@@ -904,6 +910,9 @@ ldouble: 1
 Test "Real part of: clog (0x1.fp+16383 - 0x1p-16445 i) == 11356.49165759582936919077408168801636572 - 0 i":
 ildouble: 1
 ldouble: 1
+Test "Imaginary part of: clog (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 5.0844550531823026520677817684239496041087e-32 + 1.2627468605458094918919206628466016525397 i":
+ildouble: 1
+ldouble: 1
 Test "Real part of: clog (0x1p-1074 + 0x1p-1074 i) == -744.0934983311012896593986823853525458290 + pi/4 i":
 ildouble: 1
 ldouble: 1
@@ -922,6 +931,9 @@ ldouble: 1
 Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i":
+ildouble: 1
+ldouble: 1
 Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i":
 float: 1
 ifloat: 1
@@ -1068,6 +1080,17 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
 Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i":
 ildouble: 1
 ldouble: 1
@@ -1119,6 +1142,29 @@ ldouble: 1
 Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+double: 1
+idouble: 1
 Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i":
 double: 1
 idouble: 1
@@ -1199,6 +1245,73 @@ ifloat: 1
 Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+float: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
+double: 1
+idouble: 1
 Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i":
 double: 1
 idouble: 1
@@ -3268,6 +3381,10 @@ ifloat: 1
 ildouble: 1
 ldouble: 1
 
+Function: Imaginary part of "clog":
+ildouble: 1
+ldouble: 1
+
 Function: Real part of "clog10":
 double: 1
 float: 1
diff --git a/sysdeps/ieee754/dbl-64/x2y2m1.c b/sysdeps/ieee754/dbl-64/x2y2m1.c
new file mode 100644
index 0000000..4badde3
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/x2y2m1.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO.  It is
+   given that |X| >= |Y| and the values are small enough that no
+   overflow occurs.  */
+
+static inline void
+add_split (double *hi, double *lo, double x, double y)
+{
+  /* Apply Dekker's algorithm.  */
+  *hi = x + y;
+  *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static inline void
+mul_split (double *hi, double *lo, double x, double y)
+{
+#ifdef __FP_FAST_FMA
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fma (x, y, -*hi);
+#elif defined FP_FAST_FMA
+  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
+  *hi = x * y;
+  *lo = __fma (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
+  double x1 = x * C;
+  double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  double x2 = x - x1;
+  double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+   and Q for qsort.  */
+
+static int
+compare (const void *p, const void *q)
+{
+  double pd = fabs (*(const double *) p);
+  double qd = fabs (*(const double *) q);
+  if (pd < qd)
+    return -1;
+  else if (pd == qd)
+    return 0;
+  else
+    return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+double
+__x2y2m1 (double x, double y)
+{
+  double vals[4];
+  SET_RESTORE_ROUND (FE_TONEAREST);
+  mul_split (&vals[1], &vals[0], x, x);
+  mul_split (&vals[3], &vals[2], y, y);
+  if (x >= 0.75)
+    vals[1] -= 1.0;
+  else
+    {
+      vals[1] -= 0.5;
+      vals[3] -= 0.5;
+    }
+  qsort (vals, 4, sizeof (double), compare);
+  /* Add up the values so that each element of VALS has absolute value
+     at most equal to the last set bit of the next nonzero
+     element.  */
+  for (size_t i = 0; i <= 2; i++)
+    {
+      add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+      qsort (vals + i + 1, 3 - i, sizeof (double), compare);
+    }
+  /* Now any error from this addition will be small.  */
+  return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/sysdeps/ieee754/dbl-64/x2y2m1f.c b/sysdeps/ieee754/dbl-64/x2y2m1f.c
new file mode 100644
index 0000000..fcaa708
--- /dev/null
+++ b/sysdeps/ieee754/dbl-64/x2y2m1f.c
@@ -0,0 +1,32 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+float
+__x2y2m1f (float x, float y)
+{
+  double dx = x, dy = y;
+  return (float) ((dx - 1) * (dx + 1) + dy * dy);
+}
diff --git a/sysdeps/ieee754/ldbl-128/x2y2m1l.c b/sysdeps/ieee754/ldbl-128/x2y2m1l.c
new file mode 100644
index 0000000..a249cd3
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/x2y2m1l.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO.  It is
+   given that |X| >= |Y| and the values are small enough that no
+   overflow occurs.  */
+
+static inline void
+add_split (long double *hi, long double *lo, long double x, long double y)
+{
+  /* Apply Dekker's algorithm.  */
+  *hi = x + y;
+  *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static inline void
+mul_split (long double *hi, long double *lo, long double x, long double y)
+{
+#ifdef __FP_FAST_FMAL
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fmal (x, y, -*hi);
+#elif defined FP_FAST_FMAL
+  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
+  *hi = x * y;
+  *lo = __fmal (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
+  long double x1 = x * C;
+  long double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  long double x2 = x - x1;
+  long double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+   and Q for qsort.  */
+
+static int
+compare (const void *p, const void *q)
+{
+  long double pld = fabsl (*(const long double *) p);
+  long double qld = fabsl (*(const long double *) q);
+  if (pld < qld)
+    return -1;
+  else if (pld == qld)
+    return 0;
+  else
+    return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+  long double vals[4];
+  SET_RESTORE_ROUNDL (FE_TONEAREST);
+  mul_split (&vals[1], &vals[0], x, x);
+  mul_split (&vals[3], &vals[2], y, y);
+  if (x >= 0.75L)
+    vals[1] -= 1.0L;
+  else
+    {
+      vals[1] -= 0.5L;
+      vals[3] -= 0.5L;
+    }
+  qsort (vals, 4, sizeof (long double), compare);
+  /* Add up the values so that each element of VALS has absolute value
+     at most equal to the last set bit of the next nonzero
+     element.  */
+  for (size_t i = 0; i <= 2; i++)
+    {
+      add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+      qsort (vals + i + 1, 3 - i, sizeof (long double), compare);
+    }
+  /* Now any error from this addition will be small.  */
+  return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c b/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
new file mode 100644
index 0000000..4379b68
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/x2y2m1l.c
@@ -0,0 +1,128 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO.  It is
+   given that |X| >= |Y| and the values are small enough that no
+   overflow occurs.  */
+
+static inline void
+add_split (double *hi, double *lo, double x, double y)
+{
+  /* Apply Dekker's algorithm.  */
+  *hi = x + y;
+  *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static inline void
+mul_split (double *hi, double *lo, double x, double y)
+{
+#ifdef __FP_FAST_FMA
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fma (x, y, -*hi);
+#elif defined FP_FAST_FMA
+  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
+  *hi = x * y;
+  *lo = __fma (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1 << (DBL_MANT_DIG + 1) / 2) + 1)
+  double x1 = x * C;
+  double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  double x2 = x - x1;
+  double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+   and Q for qsort.  */
+
+static int
+compare (const void *p, const void *q)
+{
+  double pd = fabs (*(const double *) p);
+  double qd = fabs (*(const double *) q);
+  if (pd < qd)
+    return -1;
+  else if (pd == qd)
+    return 0;
+  else
+    return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+  double vals[12];
+  SET_RESTORE_ROUND (FE_TONEAREST);
+  union ibm_extended_long_double xu, yu;
+  xu.d = x;
+  yu.d = y;
+  if (fabs (xu.dd[1]) < 0x1p-500)
+    xu.dd[1] = 0.0;
+  if (fabs (yu.dd[1]) < 0x1p-500)
+    yu.dd[1] = 0.0;
+  mul_split (&vals[1], &vals[0], xu.dd[0], xu.dd[0]);
+  mul_split (&vals[3], &vals[2], xu.dd[0], xu.dd[1]);
+  vals[2] *= 2.0;
+  vals[3] *= 2.0;
+  mul_split (&vals[5], &vals[4], xu.dd[1], xu.dd[1]);
+  mul_split (&vals[7], &vals[6], yu.dd[0], yu.dd[0]);
+  mul_split (&vals[9], &vals[8], yu.dd[0], yu.dd[1]);
+  vals[8] *= 2.0;
+  vals[9] *= 2.0;
+  mul_split (&vals[11], &vals[10], yu.dd[1], yu.dd[1]);
+  if (xu.dd[0] >= 0.75)
+    vals[1] -= 1.0;
+  else
+    {
+      vals[1] -= 0.5;
+      vals[7] -= 0.5;
+    }
+  qsort (vals, 12, sizeof (double), compare);
+  /* Add up the values so that each element of VALS has absolute value
+     at most equal to the last set bit of the next nonzero
+     element.  */
+  for (size_t i = 0; i <= 10; i++)
+    {
+      add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+      qsort (vals + i + 1, 11 - i, sizeof (double), compare);
+    }
+  /* Now any error from this addition will be small.  */
+  long double retval = (long double) vals[11];
+  for (size_t i = 10; i != (size_t) -1; i--)
+    retval += (long double) vals[i];
+  return retval;
+}
diff --git a/sysdeps/ieee754/ldbl-96/x2y2m1.c b/sysdeps/ieee754/ldbl-96/x2y2m1.c
new file mode 100644
index 0000000..3086fa2
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/x2y2m1.c
@@ -0,0 +1,39 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+
+#if FLT_EVAL_METHOD == 0
+
+# include <sysdeps/ieee754/dbl-64/x2y2m1.c>
+
+#else
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+double
+__x2y2m1 (double x, double y)
+{
+  return (double) __x2y2m1l (x, y);
+}
+
+#endif
diff --git a/sysdeps/ieee754/ldbl-96/x2y2m1l.c b/sysdeps/ieee754/ldbl-96/x2y2m1l.c
new file mode 100644
index 0000000..a249cd3
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/x2y2m1l.c
@@ -0,0 +1,111 @@
+/* Compute x^2 + y^2 - 1, without large cancellation error.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <math.h>
+#include <math_private.h>
+#include <float.h>
+#include <stdlib.h>
+
+/* Calculate X + Y exactly and store the result in *HI + *LO.  It is
+   given that |X| >= |Y| and the values are small enough that no
+   overflow occurs.  */
+
+static inline void
+add_split (long double *hi, long double *lo, long double x, long double y)
+{
+  /* Apply Dekker's algorithm.  */
+  *hi = x + y;
+  *lo = (x - *hi) + y;
+}
+
+/* Calculate X * Y exactly and store the result in *HI + *LO.  It is
+   given that the values are small enough that no overflow occurs and
+   large enough (or zero) that no underflow occurs.  */
+
+static inline void
+mul_split (long double *hi, long double *lo, long double x, long double y)
+{
+#ifdef __FP_FAST_FMAL
+  /* Fast built-in fused multiply-add.  */
+  *hi = x * y;
+  *lo = __builtin_fmal (x, y, -*hi);
+#elif defined FP_FAST_FMAL
+  /* Fast library fused multiply-add, compiler before GCC 4.6.  */
+  *hi = x * y;
+  *lo = __fmal (x, y, -*hi);
+#else
+  /* Apply Dekker's algorithm.  */
+  *hi = x * y;
+# define C ((1LL << (LDBL_MANT_DIG + 1) / 2) + 1)
+  long double x1 = x * C;
+  long double y1 = y * C;
+# undef C
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  long double x2 = x - x1;
+  long double y2 = y - y1;
+  *lo = (((x1 * y1 - *hi) + x1 * y2) + x2 * y1) + x2 * y2;
+#endif
+}
+
+/* Compare absolute values of floating-point values pointed to by P
+   and Q for qsort.  */
+
+static int
+compare (const void *p, const void *q)
+{
+  long double pld = fabsl (*(const long double *) p);
+  long double qld = fabsl (*(const long double *) q);
+  if (pld < qld)
+    return -1;
+  else if (pld == qld)
+    return 0;
+  else
+    return 1;
+}
+
+/* Return X^2 + Y^2 - 1, computed without large cancellation error.
+   It is given that 1 > X >= Y >= epsilon / 2, and that either X >=
+   0.75 or Y >= 0.5.  */
+
+long double
+__x2y2m1l (long double x, long double y)
+{
+  long double vals[4];
+  SET_RESTORE_ROUNDL (FE_TONEAREST);
+  mul_split (&vals[1], &vals[0], x, x);
+  mul_split (&vals[3], &vals[2], y, y);
+  if (x >= 0.75L)
+    vals[1] -= 1.0L;
+  else
+    {
+      vals[1] -= 0.5L;
+      vals[3] -= 0.5L;
+    }
+  qsort (vals, 4, sizeof (long double), compare);
+  /* Add up the values so that each element of VALS has absolute value
+     at most equal to the last set bit of the next nonzero
+     element.  */
+  for (size_t i = 0; i <= 2; i++)
+    {
+      add_split (&vals[i + 1], &vals[i], vals[i + 1], vals[i]);
+      qsort (vals + i + 1, 3 - i, sizeof (long double), compare);
+    }
+  /* Now any error from this addition will be small.  */
+  return vals[3] + vals[2] + vals[1] + vals[0];
+}
diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps
index b02b9e6..13b57cd 100644
--- a/sysdeps/x86_64/fpu/libm-test-ulps
+++ b/sysdeps/x86_64/fpu/libm-test-ulps
@@ -812,6 +812,12 @@ float: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -5.421010862427522170184200798202494495630e-20 + 3.548665303440282824232502561095699343814e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -5.960464655174753498633255797994360530379e-8 + 7.888609052210118054117285652827862296732e-31 i":
+float: 1
+ifloat: 1
 Test "Real part of: clog (0x1.000566p0 + 0x1.234p-10 i) == 8.298731898331237038231468223024422855654e-5 + 1.110938609507128729312743251313024793990e-3 i":
 float: 1
 ifloat: 1
@@ -868,6 +874,12 @@ ldouble: 1
 Test "Real part of: clog (0x1p-16445 - 0x1.fp+16383 i) == 11356.49165759582936919077408168801636572 - pi/2 i":
 ildouble: 1
 ldouble: 1
+Test "Imaginary part of: clog (0x2818p-15 + 0x798fp-15 i) == 1.5366822245016167178749091974664853785194e-08 + 1.2522014929038946066987318471922169174157 i":
+float: 1
+ifloat: 1
+Test "Real part of: clog (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 4.4469229730850767799109418892826021157328e-20 + 1.2046235979300843056806465045930070146351 i":
+ildouble: 1
+ldouble: 1
 Test "Real part of: clog (1.0 + 0x1.234566p-10 i) == 6.172834701221959432440126967147726538097e-7 + 1.111110564353742042376451655136933182201e-3 i":
 float: 1
 ifloat: 1
@@ -1009,6 +1021,21 @@ idouble: 1
 ifloat: 1
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x0.fffffffffffff8p0 + 0x0.fffffffffffff8p-1000 i) == -4.821637332766435821255375046554377090472e-17 + 4.053112396770095089737411317782466262176e-302 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffffffffffffp0 + 0x0.ffffffffffffffffp-15000 i) == -2.354315103889861110220423157644627849164e-20 + 1.541165759405643564697852372112893034397e-4516 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x0.ffffffp0 + 0x0.ffffffp-100 i) == -2.588596909321764128428416045209904492216e-8 + 3.425979381266895667295625489912064603415e-31 i":
+double: 1
+float: 2
+idouble: 1
+ifloat: 2
+ildouble: 1
+ldouble: 1
 Test "Real part of: clog10 (0x1.000566p0 + 0x1.234p-10 i) == 3.604093470239754109961125085078190708674e-5 + 4.824745078422174667425851670822596859720e-4 i":
 float: 1
 ifloat: 1
@@ -1068,6 +1095,27 @@ ldouble: 1
 Test "Real part of: clog10 (0x1.fp+16383 - 0x1p-16445 i) == 4932.061660674182269085496060792589701158 - 0 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x10673dd0f2481p-51 + 0x7ef1d17cefbd2p-51 i) == 1.3918041236396763648388478552321724382899e-29 + 0.6263795733790237053262025311642907438291 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x11682p-23 + 0x7ffed1p-23 i) == 5.0916490233953865181284669870035717560498e-13 + 0.6784968969384861816694467029319146542069 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x1367a310575591p-54 + 0x3cfcc0a0541f60p-54 i) == 2.2081507730821788480616336165447731164865e-32 + 0.5484039935757001196548030312819898864760 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x164c74eea876p-45 + 0x16f393482f77p-45 i) == -1.3155760824064879362415202279780039150764e-26 + 0.3473590599762514228227328130640352044313 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x1a6p-10 + 0x3a5p-10 i) == -6.2126412844802358329771948751248003038444e-07 + 0.4977135139537443711784513409096950995985 i":
+double: 1
+idouble: 1
 Test "Imaginary part of: clog10 (0x1p-1073 + 0x1p-1073 i) == -322.8546703496198318667349645920187712089 + pi/4*log10(e) i":
 double: 1
 idouble: 1
@@ -1151,6 +1199,75 @@ ifloat: 1
 Test "Real part of: clog10 (0x1p-8190 + 1.0 i) == 2.920285685286322365786846845062520925172e-4932 + 6.821881769209206737428918127156778851051e-1 i":
 ildouble: 1
 ldouble: 1
+Test "Real part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+double: 1
+float: 1
+idouble: 1
+ifloat: 1
+Test "Imaginary part of: clog10 (0x2818p-15 + 0x798fp-15 i) == 6.6737261053986614395049481326819059203910e-09 + 0.5438241985991753781478398141908629586460 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x2dd46725bp-35 + 0x7783a1284p-35 i) == 1.9312741086596516918394613098872836703188e-20 + 0.5231613813514771042838490538484014771862 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+float: 1
+ifloat: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x2ede88p-23 + 0x771c3fp-23 i) == -1.9440841725722970687903291200493082253766e-13 + 0.5193774116724956222518530053006822210323 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0x4447d7175p-35 + 0x6c445e00ap-35 i) == -6.4375803621988389731799033530075237868110e-21 + 0.4378257977686804492768642780897650927167 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x4d4ep-15 + 0x6605p-15 i) == -7.0781945783414996953799915941870192015212e-09 + 0.4005747524909781155537088181659175147564 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x5b06b680ea2ccp-52 + 0xef452b965da9fp-52 i) == 3.6079845358966994996207055940336690133424e-30 + 0.5243112258263349992771652393178033846555 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659b70ab7971bp-53 + 0x1f5d111e08abecp-53 i) == -1.0893543813872082317104059174982092534059e-30 + 0.5954257879188711495921161433751775633232 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x659feap-24 + 0xeaf6f9p-24 i) == 1.6200701438094619117335617123525612051457e-14 + 0.5049027913635038013499728086604870749732 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x6b10b4f3520217b6p-64 + 0xe8893cbb449253a1p-64 i) == 1.0529283395205396881397407610630442563938e-37 + 0.4947949395762683446121140513971996916447 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x81b7efa81fc35ad1p-65 + 0x1ef4b835f1c79d812p-65 i) == -4.3074341162203896332989394770760901408798e-39 + 0.5709443672155660428417571212549720987784 i":
+ildouble: 1
+ldouble: 1
+Test "Real part of: clog10 (0x8ecbf810c4ae6p-52 + 0xd479468b09a37p-52 i) == -4.2289432987513243393180377141513840878196e-30 + 0.4252020027092323591068799049905597805296 i":
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0x9b57bp-20 + 0xcb7b4p-20 i) == -1.7182001068739620267773842120965071561416e-11 + 0.3990121149225253562859800593935899629087 i":
+double: 1
+idouble: 1
+Test "Real part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+ildouble: 1
+ldouble: 1
+Test "Imaginary part of: clog10 (0xf2p-10 + 0x3e3p-10 i) == 2.6921240173351112953324592659528481616879e-06 + 0.5785726025799636431142862788413361783862 i":
+double: 1
+idouble: 1
+Test "Imaginary part of: clog10 (0xfe961079616p-45 + 0x1bc37e09e6d1p-45 i) == 2.3329549194675052736016290082882121135546e-26 + 0.4561756099441139182878993697611751382976 i":
+double: 1
+idouble: 1
 Test "Imaginary part of: clog10 (1.0 + 0x1.234566p-10 i) == 2.680828048441605163181684680300513080769e-7 + 4.825491868832381486767558728169977751564e-4 i":
 double: 1
 idouble: 1
@@ -3044,17 +3161,17 @@ ifloat: 3
 
 Function: Real part of "clog10":
 double: 2
-float: 1
+float: 2
 idouble: 2
-ifloat: 1
+ifloat: 2
 ildouble: 1
 ldouble: 1
 
 Function: Imaginary part of "clog10":
 double: 1
-float: 5
+float: 1
 idouble: 1
-ifloat: 5
+ifloat: 1
 ildouble: 1
 ldouble: 1
 

-- 
Joseph S. Myers
joseph@codesourcery.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]