// fn rem_pio2_large(x : &[f64], y : &mut [f64], e0 : i32, prec : usize) -> i32 // // Input parameters: // x[] The input value (must be positive) is broken into nx // pieces of 24-bit integers in double precision format. // x[i] will be the i-th 24 bit of x. The scaled exponent // of x[0] is given in input parameter e0 (i.e., x[0]*2^e0 // match x's up to 24 bits. // // Example of breaking a double positive z into x[0]+x[1]+x[2]: // e0 = ilogb(z)-23 // z = scalbn(z,-e0) // for i = 0,1,2 // x[i] = floor(z) // z = (z-x[i])*2**24 // // y[] ouput result in an array of double precision numbers. // The dimension of y[] is: // 24-bit precision 1 // 53-bit precision 2 // 64-bit precision 2 // 113-bit precision 3 // The actual value is the sum of them. Thus for 113-bit // precison, one may have to do something like: // // long double t,w,r_head, r_tail; // t = (long double)y[2] + (long double)y[1]; // w = (long double)y[0]; // r_head = t+w; // r_tail = w - (r_head - t); // // e0 The exponent of x[0]. Must be <= 16360 or you need to // expand the ipio2 table. // // prec an integer indicating the precision: // 0 24 bits (single) // 1 53 bits (double) // 2 64 bits (extended) // 3 113 bits (quad) // // Here is the description of some local variables: // // jk jk+1 is the initial number of terms of ipio2[] needed // in the computation. The minimum and recommended value // for jk is 3,4,4,6 for single, double, extended, and quad. // jk+1 must be 2 larger than you might expect so that our // recomputation test works. (Up to 24 bits in the integer // part (the 24 bits of it that we compute) and 23 bits in // the fraction part may be lost to cancelation before we // recompute.) // // jz local integer variable indicating the number of // terms of ipio2[] used. // // jx nx - 1 // // jv index for pointing to the suitable ipio2[] for the // computation. In general, we want // ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8 // is an integer. Thus // e0-3-24*jv >= 0 or (e0-3)/24 >= jv // Hence jv = max(0,(e0-3)/24). // // jp jp+1 is the number of terms in PIo2[] needed, jp = jk. // // q[] double array with integral value, representing the // 24-bits chunk of the product of x and 2/pi. // // q0 the corresponding exponent of q[0]. Note that the // exponent for q[i] would be q0-24*i. // // PIo2[] double precision array, obtained by cutting pi/2 // into 24 bits chunks. // // f[] ipio2[] in floating point // // iq[] integer array by breaking up q[] in 24-bits chunk. // // fq[] final product of x*(2/pi) in fq[0],..,fq[jk] // // ih integer. If >0 it indicates q[] is >= 0.5, hence // it also indicates the *sign* of the result.
/// Return the last three digits of N with y = x - N*pi/2 /// so that |y| < pi/2. /// /// The method is to compute the integer (mod 8) and fraction parts of /// (2/pi)*x without doing the full multiplication. In general we /// skip the part of the product that are known to be a huge integer ( /// more accurately, = 0 mod 8 ). Thus the number of operations are /// independent of the exponent of the input. #[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)] pub(crate) fn rem_pio2_large(x: &[f64], y: &mut [f64], e0: i32, prec: usize) -> i32 { let x1p24 = f64::from_bits(0x4170000000000000); // 0x1p24 === 2 ^ 24 let x1p_24 = f64::from_bits(0x3e70000000000000); // 0x1p_24 === 2 ^ (-24)
/* initialize jk*/ let jk = i!(INIT_JK, prec); let jp = jk;
/* determine jx,jv,q0, note that 3>q0 */ let jx = nx - 1; letmut jv = div!(e0 - 3, 24); if jv < 0 {
jv = 0;
} letmut q0 = e0 - 24 * (jv + 1); let jv = jv as usize;
/* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ letmut j = (jv as i32) - (jx as i32); let m = jx + jk; for i in0..=m {
i!(f, i, =, if j < 0 { 0.
} else {
i!(IPIO2, j as usize) as f64
});
j += 1;
}
/* compute q[0],q[1],...q[jk] */ for i in0..=jk {
fw = 0f64; for j in0..=jx {
fw += i!(x, j) * i!(f, jx + i - j);
}
i!(q, i, =, fw);
}
letmut jz = jk;
'recompute: loop { /* distill q[] into iq[] reversingly */ letmut i = 0i32;
z = i!(q, jz); for j in (1..=jz).rev() {
fw = (x1p_24 * z) as i32 as f64;
i!(iq, i as usize, =, (z - x1p24 * fw) as i32);
z = i!(q, j - 1) + fw;
i += 1;
}
/* compute n */
z = scalbn(z, q0); /* actual value of z */
z -= 8.0 * floor(z * 0.125); /* trim off integer >= 8 */
n = z as i32;
z -= n as f64;
ih = 0; if q0 > 0 { /* need iq[jz-1] to determine n */
i = i!(iq, jz - 1) >> (24 - q0);
n += i;
i!(iq, jz - 1, -=, i << (24 - q0));
ih = i!(iq, jz - 1) >> (23 - q0);
} elseif q0 == 0 {
ih = i!(iq, jz - 1) >> 23;
} elseif z >= 0.5 {
ih = 2;
}
if ih > 0 { /* q > 0.5 */
n += 1; letmut carry = 0i32; for i in0..jz { /* compute 1-q */ let j = i!(iq, i); if carry == 0 { if j != 0 {
carry = 1;
i!(iq, i, =, 0x1000000 - j);
}
} else {
i!(iq, i, =, 0xffffff - j);
}
} if q0 > 0 { /* rare case: chance is 1 in 12 */ match q0 { 1 => {
i!(iq, jz - 1, &=, 0x7fffff);
} 2 => {
i!(iq, jz - 1, &=, 0x3fffff);
}
_ => {}
}
} if ih == 2 {
z = 1. - z; if carry != 0 {
z -= scalbn(1., q0);
}
}
}
/* check if recomputation is needed */ if z == 0. { letmut j = 0; for i in (jk..=jz - 1).rev() {
j |= i!(iq, i);
} if j == 0 { /* need recomputation */ letmut k = 1; while i!(iq, jk - k, ==, 0) {
k += 1; /* k = no. of terms needed */
}
for i in (jz + 1)..=(jz + k) { /* add q[jz+1] to q[jz+k] */
i!(f, jx + i, =, i!(IPIO2, jv + i) as f64);
fw = 0f64; for j in0..=jx {
fw += i!(x, j) * i!(f, jx + i - j);
}
i!(q, i, =, fw);
}
jz += k; continue'recompute;
}
}
break;
}
/* chop off zero terms */ if z == 0. {
jz -= 1;
q0 -= 24; while i!(iq, jz) == 0 {
jz -= 1;
q0 -= 24;
}
} else { /* break z into 24-bit if necessary */
z = scalbn(z, -q0); if z >= x1p24 {
fw = (x1p_24 * z) as i32 as f64;
i!(iq, jz, =, (z - x1p24 * fw) as i32);
jz += 1;
q0 += 24;
i!(iq, jz, =, fw as i32);
} else {
i!(iq, jz, =, z as i32);
}
}
/* convert integer "bit" chunk to floating-point value */
fw = scalbn(1., q0); for i in (0..=jz).rev() {
i!(q, i, =, fw * (i!(iq, i) as f64));
fw *= x1p_24;
}
/* compute PIo2[0,...,jp]*q[jz,...,0] */ for i in (0..=jz).rev() {
fw = 0f64; letmut k = 0; while (k <= jp) && (k <= jz - i) {
fw += i!(PIO2, k) * i!(q, i + k);
k += 1;
}
i!(fq, jz - i, =, fw);
}
/* compress fq[] into y[] */ match prec { 0 => {
fw = 0f64; for i in (0..=jz).rev() {
fw += i!(fq, i);
}
i!(y, 0, =, if ih == 0 { fw } else { -fw });
} 1 | 2 => {
fw = 0f64; for i in (0..=jz).rev() {
fw += i!(fq, i);
} // TODO: drop excess precision here once double_t is used
fw = fw as f64;
i!(y, 0, =, if ih == 0 { fw } else { -fw });
fw = i!(fq, 0) - fw; for i in1..=jz {
fw += i!(fq, i);
}
i!(y, 1, =, if ih == 0 { fw } else { -fw });
} 3 => { /* painful */ for i in (1..=jz).rev() {
fw = i!(fq, i - 1) + i!(fq, i);
i!(fq, i, +=, i!(fq, i - 1) - fw);
i!(fq, i - 1, =, fw);
} for i in (2..=jz).rev() {
fw = i!(fq, i - 1) + i!(fq, i);
i!(fq, i, +=, i!(fq, i - 1) - fw);
i!(fq, i - 1, =, fw);
}
fw = 0f64; for i in (2..=jz).rev() {
fw += i!(fq, i);
} if ih == 0 {
i!(y, 0, =, i!(fq, 0));
i!(y, 1, =, i!(fq, 1));
i!(y, 2, =, fw);
} else {
i!(y, 0, =, -i!(fq, 0));
i!(y, 1, =, -i!(fq, 1));
i!(y, 2, =, -fw);
}
} #[cfg(debug_assertions)]
_ => unreachable!(), #[cfg(not(debug_assertions))]
_ => {}
}
n & 7
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-21)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.