1use json::{JsonValue, object};
2
3#[derive(Debug, Clone)]
5pub struct Pa {
6 pub data_whole: Vec<f64>,
8 data: Vec<f64>,
10 pub total: f64,
14 pub center_value: f64,
15 pub usl: f64,
17 pub lsl: f64,
19 pub std_dev_zt: f64,
21 pub std_dev_zn: f64,
23 pub std_dev_zn_data: Vec<f64>,
25 pub average_zn: f64,
27 pub average_zt: f64,
29 pub pp: f64,
31 pub ppl: f64,
32 pub ppu: f64,
33 pub ppk: f64,
34 pub cpk: f64,
36 pub cp: f64,
38 pub cpu: f64,
40 pub cpl: f64,
42 pub ppm: f64,
44 pub defects: f64,
46 pub offset_center: f64,
48 pub ca: f64,
50 pub scv: f64,
52 pub max_value: f64,
54 pub min_value: f64,
56 pub avg_r: Vec<f64>,
58
59 pub group_count: usize,
61 pub average_zn_data: Vec<f64>,
63 pub range_zn_data: Vec<f64>,
65 pub range_zn: f64,
67}
68
69impl Pa {
70 pub fn new(data: Vec<f64>, usl: f64, lsl: f64, mut group_count: usize, types: bool) -> Pa {
74 let data_whole = data.clone();
75 if group_count == 0 {
76 group_count = data.len().to_string().parse::<f64>().unwrap().sqrt() as usize;
77 }
78 if !types {
79 group_count = 0;
80 }
81 let total = data_whole.len() as f64;
82 let max_value = data_whole.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
83 let min_value = data_whole.iter().cloned().fold(f64::INFINITY, f64::min);
84
85 let center_value = (max_value + min_value) / 2.0;
86
87 let filtered_records: Vec<f64> = data_whole.clone().into_iter()
88 .filter(|&x| x > usl || x < lsl)
89 .collect::<Vec<f64>>();
90 let defects = filtered_records.len() as f64;
91
92 let mut average_zt = data_whole.iter().sum::<f64>() / data_whole.clone().len() as f64;
94 average_zt = format!("{:.4}", average_zt).parse::<f64>().unwrap();
95
96 let std_dev_zt = standard_deviation(data_whole.clone(), average_zt);
98
99
100 let mut range_zn_data = vec![];
102 let mut average_zn_data = vec![];
103 let mut std_dev_zn_data = vec![];
104 let mut average_zn = 0.0;
105 let mut range_zn = 0.0;
106 let mut std_dev_zn = 0.0;
107 let mut variance_list = vec![];
108 if group_count > 0 {
109 let data_groups = data_whole.chunks(group_count)
110 .map(|chunk| {
111 let group = chunk.to_vec();
112 let max_value = group.iter().cloned().fold(f64::NEG_INFINITY, f64::max);
114 let min_value = group.iter().cloned().fold(f64::INFINITY, f64::min);
115 range_zn_data.push(max_value - min_value);
116 let average = group.iter().sum::<f64>() / group.len() as f64;
118 average_zn_data.push(average);
119 let subgroup_variance = group.iter().map(|&x| (x - average).powi(2)).sum::<f64>() / (group.len() - 1) as f64;
121 std_dev_zn_data.push(subgroup_variance.sqrt());
122 variance_list.push(subgroup_variance);
124
125 group
126 }).collect::<Vec<Vec<f64>>>();
127
128 range_zn = range_zn_data.iter().sum::<f64>() / range_zn_data.len() as f64;
129 range_zn = format!("{:.4}", range_zn).parse::<f64>().unwrap();
130
131
132 average_zn = average_zn_data.iter().sum::<f64>() / average_zn_data.len() as f64;
133 average_zn = format!("{:.4}", average_zn).parse::<f64>().unwrap();
134
135
136 let total_dof = data_groups.iter().map(|n| (n.len() - 1) as f64).sum::<f64>();
138 let c4_value = c4(total_dof as usize);
139
140 let within_group_variance = variance_list.iter().sum::<f64>() / variance_list.len() as f64;
141 std_dev_zn = within_group_variance.sqrt() * c4_value;
142
143 std_dev_zn = format!("{:.5}", std_dev_zn).parse::<f64>().unwrap();
145 }
146
147 Self {
148 data_whole,
149 data: data.clone(),
150 average_zn,
151 range_zn,
152 total,
153 usl,
154 lsl,
155 std_dev_zt,
156 std_dev_zn,
157 pp: 0.0,
158 ppl: 0.0,
159 ppu: 0.0,
160 ppk: 0.0,
161 cpk: 0.0,
162 cp: 0.0,
163 cpu: 0.0,
164 cpl: 0.0,
165 ppm: 0.0,
166 defects,
167 offset_center: 0.0,
168 ca: 0.0,
169 scv: 0.0,
170 max_value,
171 min_value,
172 avg_r: vec![],
173 group_count,
174 average_zt,
175
176 center_value,
177 std_dev_zn_data,
179 average_zn_data,
180 range_zn_data,
181 }
182 }
183 pub fn ca(&mut self) {
185 if self.ca != 0.0 {
186 return;
187 }
188 self.scv = (self.usl + self.lsl) / 2.0;
189 self.offset_center = (self.scv - self.average_zn).abs();
190 self.ca = self.offset_center / ((self.usl - self.lsl) / 2.0);
191 self.ca = format!("{:.3}", self.ca).parse::<f64>().unwrap();
192 }
193 pub fn cpk(&mut self) {
197 if self.cpk != 0.0 {
198 return;
199 }
200 self.cp();
201 self.ca();
202 let cpk = f64::min(self.cpu, self.cpl);
203 self.cpk = format!("{:.3}", cpk).parse::<f64>().unwrap();
204 }
205 pub fn cpk_desc(&mut self) -> (&'static str, &'static str) {
207 self.cpk();
208 match self.cpk {
209 2.0.. => {
210 ("A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
211 }
212 1.67..=2.0 => {
213 ("A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
214 }
215 1.33..=1.67 => {
216 ("A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
217 }
218 1.00..=1.33 => {
219 ("B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
220 }
221 0.67..=1.00 => {
222 ("C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
223 }
224 _ => ("D", "不可接受,其能力太差,应考虑重新整改设计制程。")
225 }
226 }
227
228 pub fn ppm(&mut self) {
231 if self.ppm != 0.0 {
232 return;
233 }
234 self.ppm = (self.defects / self.total) * 1_000_000.0;
235 self.ppm = format!("{:.0}", self.ppm).parse::<f64>().unwrap();
236 }
237 pub fn cp(&mut self) {
238 if self.cp != 0.0 {
239 return;
240 }
241 self.cp = (self.usl - self.lsl) / (6.0 * self.std_dev_zn);
242
243 if self.average_zn >= self.usl {
244 self.cpu = 0.0
245 } else {
246 self.cpu = (self.usl - self.average_zn) / (3.0 * self.std_dev_zn)
247 }
248 if self.average_zn <= self.lsl {
249 self.cpl = 0.0
250 } else {
251 self.cpl = (self.average_zn - self.lsl) / (3.0 * self.std_dev_zn)
252 }
253 self.cp = format!("{:.3}", self.cp).parse::<f64>().unwrap();
254 self.cpu = format!("{:.3}", self.cpu).parse::<f64>().unwrap();
255 self.cpl = format!("{:.3}", self.cpl).parse::<f64>().unwrap();
256 }
257 #[allow(clippy::type_complexity)]
258 pub fn cp_desc(&mut self) -> ((f64, &str, &str), (f64, &str, &str), (f64, &str, &str)) {
259 self.cp();
260 let cp = match self.cp {
261 2.0.. => {
262 (self.cp, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
263 }
264 1.67..=2.0 => {
265 (self.cp, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
266 }
267 1.33..=1.67 => {
268 (self.cp, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
269 }
270 1.00..=1.33 => {
271 (self.cp, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
272 }
273 0.67..=1.00 => {
274 (self.cp, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
275 }
276 _ => (self.cp, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
277 };
278
279 let cpu = match self.cpu {
280 2.0.. => {
281 (self.cpu, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
282 }
283 1.67..=2.0 => {
284 (self.cpu, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
285 }
286 1.33..=1.67 => {
287 (self.cpu, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
288 }
289 1.00..=1.33 => {
290 (self.cpu, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
291 }
292 0.67..=1.00 => {
293 (self.cpu, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
294 }
295 _ => (self.cpu, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
296 };
297
298 let cpl = match self.cpl {
299 2.0.. => {
300 (self.cpl, "A++", "过程非常稳定,质量控制良好,可考虑降低成本。")
301 }
302 1.67..=2.0 => {
303 (self.cpl, "A+", "质量控制良好,过程基本稳定,但仍有改进的潜力。")
304 }
305 1.33..=1.67 => {
306 (self.cpl, "A", "过程基本稳定,但存在改进的空间,质量控制较为良好。")
307 }
308 1.00..=1.33 => {
309 (self.cpl, "B", "过程接近边界,质量控制需要改进,但可能仍能满足一些标准。")
310 }
311 0.67..=1.00 => {
312 (self.cpl, "C", "过程不稳定,质量控制问题严重,需要立即调整和改进。")
313 }
314 _ => (self.cpl, "D", "不可接受,其能力太差,应考虑重新整改设计制程。")
315 };
316 (cpu, cp, cpl)
317 }
318
319 pub fn normal_distribution_plot(&mut self) -> Vec<Vec<f64>> {
321 let list = vec![
322 vec![self.scv - self.std_dev_zt * 3.0, self.scv - self.std_dev_zt * 2.0],
323 vec![self.scv - self.std_dev_zt * 2.0, self.scv - self.std_dev_zt * 1.0],
324 vec![self.scv - self.std_dev_zt * 1.0, self.scv],
325 vec![self.scv, self.scv + self.std_dev_zt * 1.0],
326 vec![self.scv + self.std_dev_zt * 1.0, self.scv + self.std_dev_zt * 2.0],
327 vec![self.scv + self.std_dev_zt * 2.0, self.scv + self.std_dev_zt * 3.0]
328 ];
329 let mut counts = vec![0.0; list.len()];
331 for &value in self.data.iter() {
332 for (index, item) in list.iter().enumerate() {
333 if value >= item[0] && value < item[1] {
334 counts[index] += 1.0;
335 break;
336 }
337 }
338 }
339
340 list
341 }
342
343 pub fn xbar_r(&mut self) -> JsonValue {
345 let x_ucl = self.average_zn + a2(self.group_count) * self.range_zn;
346 let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
347
348 let x_lcl = self.average_zn - a2(self.group_count) * self.range_zn;
349 let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
350
351 let r_ucl = format!("{:.3}", d4(self.group_count) * self.range_zn).parse::<f64>().unwrap();
352 let r_lcl = 0.00;
353
354 object! {
355 group_count:self.group_count,
356 usl:self.usl,
357 lsl:self.lsl,
358 x_double_bar:self.average_zn,
359 x_ucl:x_ucl,
360 x_lcl:x_lcl,
361 average_zn_data:self.average_zn_data.clone(),
362 r_double_bar:self.range_zn,
363 r_ucl:r_ucl,
364 r_lcl:r_lcl,
365 range_data: self.range_zn_data.clone()
366 }
367 }
368 pub fn xbar_s(&mut self) -> JsonValue {
370 let mut std_dev_zn = self.std_dev_zn_data.iter().sum::<f64>() / self.std_dev_zn_data.len() as f64;
371 std_dev_zn = format!("{:.3}", std_dev_zn).parse::<f64>().unwrap();
372 if std_dev_zn.is_nan() {
373 std_dev_zn = 0.0;
374 }
375
376 let x_ucl = self.average_zn + a3(self.group_count) * std_dev_zn;
377 let x_lcl = self.average_zn - a3(self.group_count) * std_dev_zn;
378
379 let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
380 let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
381
382 let s_ucl = b4(self.group_count) * std_dev_zn;
383 let s_ucl = format!("{:.3}", s_ucl).parse::<f64>().unwrap();
384
385 let s_lcl = b3(self.group_count) * std_dev_zn;
386
387 object! {
388 group_count:self.group_count,
389 usl:self.usl,
390 lsl:self.lsl,
391 x_double_bar:self.average_zn,
392 x_ucl:x_ucl,
393 x_lcl:x_lcl,
394 average_zn_data:self.average_zn_data.clone(),
395 s_double_bar:std_dev_zn,
396 s_ucl:s_ucl,
397 s_lcl:s_lcl,
398 std_dev_zn_data: self.std_dev_zn_data.clone()
399 }
400 }
401 pub fn xbar(&mut self) -> (f64, f64, f64) {
403 let x_ucl = self.average_zn + a2(self.group_count) * self.range_zn;
404 let x_ucl = format!("{:.3}", x_ucl).parse::<f64>().unwrap();
405
406 let x_lcl = self.average_zn - a2(self.group_count) * self.range_zn;
407 let x_lcl = format!("{:.3}", x_lcl).parse::<f64>().unwrap();
408
409 (self.average_zn, x_ucl, x_lcl)
410 }
411 pub fn i_mr(&mut self) -> JsonValue {
414 object! {
417
418 }
419 }
420 pub fn u(&mut self) -> (f64, Vec<f64>) {
423 (self.average_zt, self.data.clone())
424 }
425 pub fn p(&mut self) -> (f64, Vec<f64>) {
428 let len = self.data.len() as f64;
429 let p_list = self.data.clone().iter().map(|&x| {
430 x / len
431 }).collect::<Vec<f64>>();
432 let p = p_list.iter().sum::<f64>() / p_list.len() as f64;
433 (p, p_list)
434 }
435 pub fn np(&mut self) -> (f64, f64, Vec<f64>) {
438 let u6 = self.average_zt + 4.0 * self.std_dev_zt;
439 (self.average_zt, u6, self.data.clone())
440 }
441
442 fn get_pp(&mut self) {
443 if self.pp != 0.0 {
444 return;
445 }
446 self.pp = (self.usl - self.lsl) / (6.0 * self.std_dev_zt);
447 self.pp = format!("{:.3}", self.pp).parse::<f64>().unwrap()
448 }
449 fn get_ppl(&mut self) {
450 if self.ppl != 0.0 {
451 return;
452 }
453 self.ppl = (self.average_zt - self.lsl) / (3.0 * self.std_dev_zt);
454 self.ppl = format!("{:.3}", self.ppl).parse::<f64>().unwrap()
455 }
456 fn get_ppu(&mut self) {
457 if self.ppu != 0.0 {
458 return;
459 }
460 self.ppu = (self.usl - self.average_zt) / (3.0 * self.std_dev_zt);
461 self.ppu = format!("{:.3}", self.ppu).parse::<f64>().unwrap()
462 }
463 fn get_ppk(&mut self) {
464 if self.ppk != 0.0 {
465 return;
466 }
467 self.get_ppl();
468 self.get_ppu();
469 self.ppk = f64::min(self.ppu, self.ppl);
470 self.ppk = format!("{:.3}", self.ppk).parse::<f64>().unwrap()
471 }
472 pub fn histogram(&mut self) -> JsonValue {
474 self.get_pp();
475 self.get_ppl();
476 self.get_ppu();
477 self.get_ppk();
478 self.cp();
479 self.cpk();
480 self.ppm();
481
482 let _bin_width = (self.max_value - self.min_value) / 6.0;
483
484 let mut histogram = object! {};
485 for &value in self.data_whole.iter() {
486 if histogram[value.to_string()].is_empty() {
487 histogram[value.to_string()] = 1.0.into();
488 }
489 histogram[value.to_string()] = (histogram[value.to_string()].as_f64().unwrap() + 1.0).into();
490 }
491
492 object! {
493 usl:self.usl,
494 lsl:self.lsl,
495 histogram:histogram,
496 std_dev_zn_data:self.std_dev_zn_data.clone()
497 }
498 }
499
500 pub fn normal_distribution(&mut self) -> JsonValue {
502 let mut normal_distribution = object! {};
503 for item in self.data_whole.clone().iter_mut() {
504 if normal_distribution[item.clone().to_string().as_str()].is_empty() {
505 normal_distribution[item.clone().to_string().as_str()] = 1.into();
506 } else {
507 normal_distribution[item.clone().to_string().as_str()] = JsonValue::from(normal_distribution[item.clone().to_string().as_str()].clone().to_string().parse::<i32>().unwrap() + 1);
508 }
509 }
510
511 object! {
512 usl:self.usl,
513 lsl:self.lsl,
514 min:self.min_value,
515 max:self.max_value,
516 std_dev_zt:self.std_dev_zt,
517 average_zt:self.average_zt,
518 normal_distribution:normal_distribution,
519 }
520 }
521}
522
523fn standard_deviation(data: Vec<f64>, mean: f64) -> f64 {
525 let variance = data.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (data.len() as f64 - 1.0);
526 format!("{:.5}", variance.sqrt()).parse::<f64>().unwrap()
527}
528
529fn a2(len: usize) -> f64 {
531 match len {
532 2 => 1.880,
533 3 => 1.023,
534 4 => 0.729,
535 5 => 0.577,
536 6 => 0.483,
537 7 => 0.149,
538 8 => 0.373,
539 9 => 0.337,
540 10 => 0.308,
541 11 => 0.285,
542 12 => 0.266,
543 13 => 0.249,
544 14 => 0.235,
545 15 => 0.223,
546 16 => 0.212,
547 17 => 0.203,
548 18 => 0.194,
549 19 => 0.187,
550 20 => 0.180,
551 21 => 0.173,
552 22 => 0.167,
553 23 => 0.162,
554 24 => 0.157,
555 25 => 0.153,
556 _ => 0.0
557 }
558}
559
560fn a3(len: usize) -> f64 {
562 match len {
563 2 => 2.659,
564 3 => 1.954,
565 4 => 1.628,
566 5 => 1.427,
567 6 => 1.287,
568 7 => 1.182,
569 8 => 1.099,
570 9 => 1.032,
571 10 => 0.975,
572 11 => 0.927,
573 12 => 0.886,
574 13 => 0.850,
575 14 => 0.817,
576 15 => 0.789,
577 16 => 0.763,
578 17 => 0.739,
579 18 => 0.718,
580 19 => 0.698,
581 20 => 0.680,
582 _ => 0.0
583 }
584}
585
586fn b3(len: usize) -> f64 {
588 match len {
589 2 => 0.0,
590 3 => 0.0,
591 4 => 0.0,
592 5 => 0.0,
593 6 => 0.03,
594 7 => 0.118,
595 8 => 0.185,
596 9 => 0.239,
597 10 => 0.284,
598 11 => 0.321,
599 12 => 0.354,
600 13 => 0.382,
601 14 => 0.406,
602 15 => 0.428,
603 16 => 0.448,
604 17 => 0.446,
605 18 => 0.482,
606 19 => 0.497,
607 20 => 0.510,
608 _ => 0.0
609 }
610}
611
612fn b4(len: usize) -> f64 {
614 match len {
615 2 => 3.267,
616 3 => 2.568,
617 4 => 2.266,
618 5 => 2.089,
619 6 => 1.970,
620 7 => 1.882,
621 8 => 1.815,
622 9 => 1.761,
623 10 => 1.716,
624 11 => 1.679,
625 12 => 1.646,
626 13 => 1.618,
627 14 => 1.594,
628 15 => 1.572,
629 16 => 1.552,
630 17 => 1.534,
631 18 => 1.518,
632 19 => 1.503,
633 20 => 1.490,
634 _ => 0.0
635 }
636}
637
638fn c4(len: usize) -> f64 {
640 match len {
641 2 => 0.79785,
642 3 => 0.87153,
643 4 => 0.905763,
644 5 => 0.925222,
645 6 => 0.937892,
646 7 => 0.946837,
647 8 => 0.953503,
648 9 => 0.958669,
649 10 => 0.962793,
651 11 => 0.966163,
653 12 => 0.968968,
654 13 => 0.971341,
655 14 => 0.973375,
656 15 => 0.975137,
657 16 => 0.976679,
658 17 => 0.978039,
659 18 => 0.979249,
660 19 => 0.980331,
661 20 => 0.981305,
662 21 => 0.982187,
663 22 => 0.982988,
664 23 => 0.98372,
665 24 => 0.984391,
666 25 => 0.985009,
667 26 => 0.985579,
668 27 => 0.986107,
669 28 => 0.986597,
670 29 => 0.987054,
671 30 => 0.98748,
672 31 => 0.987878,
673 32 => 0.988252,
674 33 => 0.988603,
675 34 => 0.988934,
676 35 => 0.989246,
677 36 => 0.98954,
678 37 => 0.989819,
679 38 => 0.990083,
680 39 => 0.990333,
681 40 => 0.990571,
682 41 => 0.990797,
683 42 => 0.991013,
684 43 => 0.991218,
685 44 => 0.991415,
686 45 => 0.991602,
687 46 => 0.991782,
688 47 => 0.991953,
689 48 => 0.992118,
690 49 => 0.992276,
691 50 => 0.992427,
692 51 => 0.992573,
693 52 => 0.992713,
694 53 => 0.992848,
695 54 => 0.992978,
696 55 => 0.993103,
697 56 => 0.993224,
698 57 => 0.99334,
699 58 => 0.993452,
700 59 => 0.993561,
701 60 => 0.993666,
702 61 => 0.993767,
703 62 => 0.993866,
704 63 => 0.993961,
705 64 => 0.994053,
706 65 => 0.994142,
707 66 => 0.994229,
708 67 => 0.994313,
709 68 => 0.994395,
710 69 => 0.994474,
711 70 => 0.994551,
712 71 => 0.994626,
713 72 => 0.994699,
714 73 => 0.994769,
715 74 => 0.994838,
716 75 => 0.994905,
717 76 => 0.99497,
718 77 => 0.995034,
719 78 => 0.995096,
720 79 => 0.995156,
721 80 => 0.995215,
722 81 => 0.995272,
723 82 => 0.995328,
724 83 => 0.995383,
725 84 => 0.995436,
726 85 => 0.995489,
727 86 => 0.995539,
728 87 => 0.995589,
729 88 => 0.995638,
730 89 => 0.995685,
731 90 => 0.995732,
732 91 => 0.995777,
733 92 => 0.995822,
734 93 => 0.995865,
735 94 => 0.995908,
736 95 => 0.995949,
737 96 => 0.99599,
738 97 => 0.996030,
739 98 => 0.996069,
740 99 => 0.996108,
741 100 => 0.996145,
742 101 => 0.996182,
743 102 => 0.996218,
744 103 => 0.996253,
745 104 => 0.996288,
746 105 => 0.996322,
747 106 => 0.996356,
748 107 => 0.996389,
749 108 => 0.996421,
750 109 => 0.996452,
751 110 => 0.996483,
752 111 => 0.996514,
753 112 => 0.996544,
754 113 => 0.996573,
755 114 => 0.996602,
756 115 => 0.996631,
757 116 => 0.996658,
758 117 => 0.996686,
759 118 => 0.996713,
760 _ => 0.0,
761 }
762}
763
764fn d4(len: usize) -> f64 {
828 match len {
829 2 => 3.267,
830 3 => 2.574,
831 4 => 2.282,
832 5 => 2.114,
833 6 => 2.004,
834 7 => 1.924,
835 8 => 1.864,
836 9 => 1.816,
837 10 => 1.777,
838 11 => 1.744,
839 12 => 1.717,
840 13 => 1.693,
841 14 => 1.672,
842 15 => 1.653,
843 16 => 1.637,
844 17 => 1.622,
845 18 => 1.608,
846 19 => 1.597,
847 20 => 1.585,
848 21 => 1.575,
849 22 => 1.566,
850 23 => 1.557,
851 24 => 1.548,
852 25 => 1.541,
853 _ => 0.0
854 }
855}
856
857#[test]
858fn test() {
859 let cp = (10.0 - 8.0) / (6.0 * 0.5);
860 let cp = format!("{:.3}", cp).parse::<f64>().unwrap();
861 assert_eq!(cp, 0.667)
862}
863
864#[test]
865fn ppm_test() {
866 let cp = (10.0 - 8.0) / (6.0 * 0.5);
867 let cp = format!("{:.3}", cp).parse::<f64>().unwrap();
868 assert_eq!(cp, 0.667)
869}