Divide two numbers, with SQL dialect-3 semantics, as in the blr_version5 ... blr_divide or blr_version5 ... blr_average ....
| 2483 | // Divide two numbers, with SQL dialect-3 semantics, as in the blr_version5 ... blr_divide or |
| 2484 | // blr_version5 ... blr_average .... |
| 2485 | dsc* ArithmeticNode::divide2(const dsc* desc, impure_value* value) const |
| 2486 | { |
| 2487 | thread_db* tdbb = JRD_get_thread_data(); |
| 2488 | DEV_BLKCHK(node, type_nod); |
| 2489 | |
| 2490 | // Handle decimal arithmetic |
| 2491 | |
| 2492 | if (nodFlags & FLAG_DECFLOAT) |
| 2493 | { |
| 2494 | const Decimal128 d1 = MOV_get_dec128(tdbb, desc); |
| 2495 | const Decimal128 d2 = MOV_get_dec128(tdbb, &value->vlu_desc); |
| 2496 | |
| 2497 | DecimalStatus decSt = tdbb->getAttachment()->att_dec_status; |
| 2498 | value->vlu_misc.vlu_dec128 = d2.div(decSt, d1); |
| 2499 | |
| 2500 | value->vlu_desc.dsc_dtype = dtype_dec128; |
| 2501 | value->vlu_desc.dsc_length = sizeof(Decimal128); |
| 2502 | value->vlu_desc.dsc_scale = 0; |
| 2503 | value->vlu_desc.dsc_sub_type = 0; |
| 2504 | value->vlu_desc.dsc_address = (UCHAR*) &value->vlu_misc.vlu_dec128; |
| 2505 | |
| 2506 | return &value->vlu_desc; |
| 2507 | } |
| 2508 | |
| 2509 | // 128-bit arithmetic |
| 2510 | |
| 2511 | if (nodFlags & FLAG_INT128) |
| 2512 | { |
| 2513 | const SSHORT scale = NUMERIC_SCALE(*desc); |
| 2514 | const Int128 d2 = MOV_get_int128(tdbb, desc, scale); |
| 2515 | const Int128 d1 = MOV_get_int128(tdbb, &value->vlu_desc, nodScale - scale); |
| 2516 | |
| 2517 | value->vlu_misc.vlu_int128 = d1.div(d2, scale * 2); |
| 2518 | |
| 2519 | value->vlu_desc.dsc_dtype = dtype_int128; |
| 2520 | value->vlu_desc.dsc_length = sizeof(Int128); |
| 2521 | value->vlu_desc.dsc_scale = nodScale; |
| 2522 | setFixedSubType(&value->vlu_desc, *desc, value->vlu_desc); |
| 2523 | value->vlu_desc.dsc_address = (UCHAR*) &value->vlu_misc.vlu_int128; |
| 2524 | |
| 2525 | return &value->vlu_desc; |
| 2526 | } |
| 2527 | |
| 2528 | // Handle floating arithmetic |
| 2529 | |
| 2530 | if (nodFlags & FLAG_DOUBLE) |
| 2531 | { |
| 2532 | const double d2 = MOV_get_double(tdbb, desc); |
| 2533 | if (d2 == 0.0) |
| 2534 | { |
| 2535 | ERR_post(Arg::Gds(isc_arith_except) << |
| 2536 | Arg::Gds(isc_exception_float_divide_by_zero)); |
| 2537 | } |
| 2538 | const double d1 = MOV_get_double(tdbb, &value->vlu_desc); |
| 2539 | value->vlu_misc.vlu_double = d1 / d2; |
| 2540 | if (std::isinf(value->vlu_misc.vlu_double)) |
| 2541 | { |
| 2542 | ERR_post(Arg::Gds(isc_arith_except) << |
nothing calls this directly
no test coverage detected