use std::ops::Shr; #[test] pub fn test_conversion_u16() { let actual = (u64::MIN..=u16::MAX as u64).into_iter().sum::()/(u16::MAX as u64+1); let mut average = 0.0; let fac = 1.0/u16::MAX as f32; for f in u16::MIN..=u16::MAX { average += f as f32 * fac; } assert_eq!(actual, average as u64); } fn hash(x: u8) -> u8 { let mut k = (x as f32 * 349857.3456).sin(); k = k - k.floor(); (k * 255.) as u8 } #[test] pub fn test_arithmetic() { let lum_f32 = |r: f32, g: f32, b: f32| { 0.2126 * r + 0.7152 * g + 0.0722 * b }; let lum_u8 = |r: u8, g: u8, b: u8| { (r as u64 * 913110047u64).shr(32) + (g as u64 * 3071760610u64).shr(32) + (b as u64 * 310096639u64).shr(32) }; let mut colors = Vec::new(); for a in 1..4096i32 { colors.push((hash(a as u8), hash(a.wrapping_sub(98) as u8), hash(a.wrapping_add(178) as u8))); } let lum0 = colors.iter().map(|(a,b,c)| lum_f32(*a as f32, *b as f32, *c as f32)).sum::() / colors.len() as f32; let lum1 = colors.iter().map(|(a,b,c)| lum_u8(*a,*b,*c) as u64).sum::() / colors.len() as u64; let mut lum2 = 0.; let w = 1./colors.len() as f32; for (r,g,b) in colors.iter() { let a = lum_f32(*r as f32, *g as f32, *b as f32); lum2 += a * w; } println!("{lum0}"); println!("{lum2}"); println!("{lum1}"); let lf = (lum_f32(1., 0.5, 0.333) * 255.0) as u8; println!("{lf}"); let lu = lum_u8(255, 127, 85); println!("{lu}"); }