Incorrect arithmetic in bigdecimal

Hello,
I attempting to do some simple arithmetic (for FX rate conversion) using BigDecimal that is generating incorrect results (while the same calculation with double works correctly).
Can someone please take a look at this sample program and tell me what I may be doing wrong? Or, at least provide some insight into what is going wrong so that I can take steps to avoid?
import static java.math.RoundingMode.HALF_UP;
import java.math.BigDecimal;
import java.math.MathContext;
public class BigDecimalTest {
      public static void main(String[] args) {
            // 15,000,000,000,000
            BigDecimal large_value = new BigDecimal("15000000000000");
            MathContext mc = new MathContext(16, HALF_UP);
            BigDecimal divisor = new BigDecimal("1.5");
            BigDecimal numerator = BigDecimal.ONE.divide(divisor, mc);
            BigDecimal resultOne = large_value.multiply(numerator);
            BigDecimal resultTwo = large_value.divide(divisor, mc);
            System.out.println("Big Decimal arithmetic:");
            System.out.println("15 trillion * (1/1.5) = ["+resultOne.toPlainString()+"]");
            System.out.println("15 trillion / 1.5 = ["+resultTwo.toPlainString()+"]");
            System.out.println("results compare as ["+resultOne.compareTo(resultTwo)+"]\n");
            double large_dbl_value = 15000000000000d;
            double divisorDbl = 1.5;
            double resultOneDbl = large_dbl_value * (1/divisorDbl);
            double resultTwoDbl = large_dbl_value / divisorDbl;
            System.out.println("double arithmetic:");
            System.out.println("15 trillion * (1/1.5) = ["+resultOneDbl+"]");
            System.out.println("15 trillion /1.5 = ["+resultTwoDbl+"]");
            System.out.println("results compare as ["+(resultOneDbl - resultTwoDbl)+"]");
}Thank you,
Ed Bridges

When I look more into the proposed solution -- for example in the code below -- I still see discrepancies in the arithmetic of BigDecimal and double:
import static java.math.RoundingMode.HALF_UP;
import java.math.BigDecimal;
import java.math.MathContext;
public class BigDecimalTest {
     public static void main(String[] args) {
          // 12,345,678,901,234
          BigDecimal large_value = new BigDecimal("12345678901234");
          MathContext mc = new MathContext(16, HALF_UP);
          for (int i = 80; i< 90; i++) {           
               BigDecimal rate = new BigDecimal(i).divide(new BigDecimal("100.0"));
               BigDecimal divisor = rate.setScale(16, HALF_UP);
               BigDecimal numerator = divisor.pow(-1, mc);
               BigDecimal resultOne = large_value.multiply(numerator).round(mc);
               BigDecimal resultTwo = large_value.divide(divisor, mc);
               if (resultOne.compareTo(resultTwo)!= 0) {
                    System.out.println("Big Decimal arithmetic:");
                    System.out.println(large_value + " * (1/" + rate + ") = ["+resultOne.toPlainString()+"]");
                    System.out.println(large_value + " / " + rate + " = ["+resultTwo.toPlainString()+"]");
                    System.out.println("results compare as ["+resultOne.compareTo(resultTwo)+"]\n");
          double large_dbl_value = 12345678901234d;
          for (int i = 80; i< 90; i++) {           
               double divisorDbl = i / 100;
               double resultOneDbl = large_dbl_value * (1/divisorDbl);
               double resultTwoDbl = large_dbl_value / divisorDbl;
               if (resultOneDbl != resultTwoDbl) {
                    System.out.println("double arithmetic:");
                    System.out.println(large_dbl_value + " * (1/" + divisorDbl + ") = ["+resultOneDbl+"]");
                    System.out.println(large_dbl_value + " / " + divisorDbl + " = ["+resultTwoDbl+"]");
                    System.out.println("results compare as ["+(resultOneDbl - resultTwoDbl)+"]");
}This produces the following result:
Big Decimal arithmetic:
12345678901234 * (1/0.86) = [14355440582830.24]
12345678901234 / 0.86 = [14355440582830.23]
results compare as [1]
Big Decimal arithmetic:
12345678901234 * (1/0.89) = [13871549327229.22]
12345678901234 / 0.89 = [13871549327229.21]
results compare as [1]It's these "off-by-one penny" errors that are killing me :-(

Similar Messages

  • Error on floating point?

    One can expect that 1.2 * 3.0 equals 3.60
    But the following statement has the result: 3.5999999999999996
    - System.out.println(1.2 * 3.0);
    Why?
    How can I control or estimate the floating point error?
    Thanks in advance!

    It is not a Java problem or a Java error. It is inherent to floating-point arithmetic.
    1.2 can not be exactly represented in binary floating-point arithmetic. But 1.25 (that is 5 * (2 ^ -2)) can be.
    If your problem requires exact decimal arithmetic, use BigDecimal instead. (It is very slow compared to the conventional floating-point arithmetic).
    Please consult a textbook on numerical calculus for the techniques of dealing with floating-point error - it depends on the algorithm that you use for solving your problem.

  • Add 2 strings together

    Hello,
    i have a really weird error message here:
    say I define 2 dta type c objects:
    data: tot_str(50) type c,
          sub_str(20) type c.
    then I do
        tot_str = 'ABCDEF' & substr
    assuming both tot_str and sub_str are already initialized.
    However, the error message I got is:
    Incorrect arithmetic or bit expression: Instead of "&", an operator (+,     -, *, /, ... or BIT-AND, BIT-XOR, BIT-OR) was expected.)
    Why is it so? I thought & is the standard concatenation character for ABAP. And BTW, when I changed to +, it will give me a run-time error saying that the 2 strings can not be added....
    Thanks a lot!
    Regards,
    Anyi

    Hi Anyi,
    yes you are right. I found it in SAP help hidden somewhere in the data objects section:
    "If you want to enter a character literal in the ABAP Editor that is longer than a single editor line, ABAP syntax allows you to enter several character literals and link them using the & character. "
    So this was just a crutch to bypass the (meanwhile obsolete) editor line length limit.
    I the section "Processing Character Strings", chapter "Concatenating Character Strings", they say:
    "The CONCATENATE statement combines two or more separate strings into one.
    CONCATENATE <c1> ... <cn> INTO <c> [SEPARATED BY <s>].
    This statement concatenates the character fields <c1> to <cn> and assigns the result to <c>. The system ignores spaces at the end of the individual source strings.
    The addition SEPARATED BY <s> allows you to specify a character field <s> which is placed in its defined length between the individual fields."
    That means that all leading and trailing spaces will disappear except the ones in the separator string <sep>.
    So it depends on the result you want as how to do the concatenation. if you want a fixed position regardless of blanks, then you must work with offset and length addition.
    Kind regards,
    Clemens

  • Pls find this error,say me what to do

    here i am passing a string into itab,it gives me error
    "Incorrect arithmetic or bit expression: Instead of "'snap, 1/2" Ring"
    below is the code
    ITAB-TEXT =
    'SUPH000001||0000114731||H||H-Hardware||H-1164-||Trigger'
    'snap, 1/2" Ring (QCL175)||||0000206554||||rm1||06/26/2006||3||FT||'
    '06/26/2006||07/12/2006||07/26/2006||07/25/2006||07/25/2006||07/'
    '27/2006||3.000||||||239||||||||u||aswani||20060713||aswani||20060713'
    '||01/2006||9000000126||00040||0001'.
    APPEND ITAB.
    Incorrect arithmetic or bit expression: Instead of "'snap, 1/2" Ring

    Hello,
    Is the whole string is 'SUPH000001||0000114731||H||H-Hardware||H-1164-||Trigger'
    'snap, 1/2" Ring (QCL175)||||0000206554||||rm1||06/26/2006||3||FT||'
    '06/26/2006||07/12/2006||07/26/2006||07/25/2006||07/25/2006||07/'
    '27/2006||3.000||||||239||||||||u||aswani||20060713||aswani||20060713'
    '||01/2006||9000000126||00040||0001'. this .
    or every line is a string.
    If every line is a string then do like this.
    ITAB-TEXT = 'SUPH000001||0000114731||H||H-Hardware||H-1164-||Trigger'.
    append itab.
    itab-text = 'snap, 1/2" Ring (QCL175)||||0000206554||||rm1||06/26/2006||3||FT||'
    append itab.
    If the whole para is string, then remove the '.
    ie:
    ITAB-TEXT =
    'SUPH000001||0000114731||H||H-Hardware||H-1164-||Trigger
    snap, 1/2" Ring (QCL175)||||0000206554||||rm1||06/26/2006||3||FT||
    06/26/2006||07/12/2006||07/26/2006||07/25/2006||07/25/2006||07/
    27/2006||3.000||||||239||||||||u||aswani||20060713||aswani||20060713
    ||01/2006||9000000126||00040||0001'.
    APPEND ITAB.
    if useful reward points.
    Regards,
    Vasanth

  • Is it possible to write " Condtab = TA_DOCSET_RES-FLD cutoff_date "

    Hi All experts,
    cutoff_date = today - wa_itab-field.
    I want to write like this " Condtab = TA_DOCSET_RES-FLD > cutoff_date ".
    But it is giving this error
    " Incorrect arithmetic or Bit expression: Instead of "GT", an operator ( +,-,*, / )
    was expected.
    So can you please tell me how to write this.
    Thanks,
    Basu

    Hi,
    You cant write like,
    Condtab = TA_DOCSET_RES-FLD > cutoff_date ".
    This type of operationis not permitted by system.
    But tou can write like,
    Condtab = TA_DOCSET_RES-FLD + cutoff_date ".
    Thanks.
    Message was edited by:
            Viji

  • Catch

    what is the use catch and endcatch in bapi programming

    Hi,
    You can handle with this way some incorrect arithmetic operation, like division by zero...
    Your program will not have a short dump, keeps the control, and you can write a nice error handling.
    Note: there are catchable and non-catchable exceptions. Non-catchable ones will cause ABAP dump, even when they are between CATCH-ENDCATCH.
    DATA: result TYPE i,
    number TYPE i.
    CATCH SYSTEM-EXCEPTIONS arithmetic_errors = 4
    OTHERS = 8.
    result = 1 / number.
    ENDCATCH.
    IF sy-subrc 0.
    ENDIF.
    Regards,
    Shiva.

  • Strange error while executing a stored procedure: Incorrect syntax near '@p0'

    All, I am getting a strange error while executing a stored procedure: Incorrect syntax near '@p0'  using JDBC CallableStatment.
    Here is my code...
    CallableStatement cStmt = con.prepareCall("{call SET CHAINED ON EXEC <dbName>.<schemaName>.<SPName> (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)}");
    cStmt.setString(1, "2012005881");
    cStmt.setString(2, "07");
    cStmt.setString(3, "10");
    cStmt.setString(4, "Case title");
    cStmt.setString(5, "Open");
    java.sql.Date dt1 = new java.sql.Date(2014,10,20);
    cStmt.setDate(6, dt1);
    cStmt.setString(7, "01");
    cStmt.setString(8, "N");
    cStmt.setString(9, "ADA Test");
    cStmt.setString(10, "N");
    cStmt.setString(11, "English");
    cStmt.setString(12, "N");
    cStmt.setString(13, "N");
    cStmt.setString(14, "N");
    cStmt.setString(15, "N");
    cStmt.setString(16, "N");
    cStmt.setString(17, "N");
    cStmt.setString(18, "07");
    cStmt.setString(19, "10");
    cStmt.setString(20, "juache0");
    java.sql.Date dt2 = new java.sql.Date(2014,10,20);
    java.sql.Date dt3 = new java.sql.Date(2014,10,20);
    cStmt.setDate(21, dt2);
    cStmt.setDate(22, dt3);
    cStmt.setString(23, "userid0");
    cStmt.setString(24, "");
    cStmt.setString(25, "");  
    cStmt.setString(26, "");
    java.math.BigDecimal bg1 = new java.math.BigDecimal(10);
    cStmt.setBigDecimal(27, bg1);
    cStmt.setString(28, "userid");
    cStmt.setString(29, "userid");
    int hadResults = cStmt.executeUpdate();
    Your help is greatly appreciated.
    I am executing the above using Jconnect3.0 driver, inside WebSphere Application Server V8.0
    Thanks
    Nags

    NOTE: I don't work with JDBC/jConnect so (at this point) just some questions ...
    1 - are you sending this to ASE, ASA, IQ, or some other RDBMS?
    2 - what is the value of <schemaname>?
    3 - do you have other prepareCall() instances that successfully call a stored proc? [would be interesting to see if there's a difference in the format of the calls]
    A quick google search shows a couple ways to submit a stored proc execution to the RDBMS, with the format depending on the format expected by the target RDBMS.
    I'm wondering if you really need/want the parentheses around the argument list, ie, what happens if you change
    from
    -- parentheses around args
    EXEC <dbName>.<schemaName>.<SPName> ( ?,?,?,?,?,...,? )
    to
    -- no parentheses around args
    EXEC <dbName>.<schemaName>.<SPName> ?,?,?,?,?,...,?
    In ASE if I wrap the parameters in parentheses I get the same error you're getting:
    ================== w/ parentheses => error
    1> sp_who (sa)
    2> go
    Msg 102, Level 15, State 1:
    Server 'CC1_V1', Line 1:
    Incorrect syntax near 'sa'.   <<=== sa == @p0 ??
    ================== w/out parentheses => works
    1> sp_who sa
    2> go
    fid spid status  loginame origname ...
       0   17 running sa       sa       ...
    ==================

  • Inline functions in C, gcc optimization and floating point arithmetic issues

    For several days I really have become a fan of Alchemy. But after intensive testing I have found several issues which I'd like to solve but I can't without any help.
    So...I'm porting an old game console emulator written by me in ANSI C. The code is working on both gcc and VisualStudio without any modification or crosscompile macros. The only platform code is the audio and video output which is out of scope, because I have ported audio and video witin AS3.
    Here are the issues:
    1. Inline functions - Having only a single inline function makes the code working incorrectly (although not crashing) even if any optimization is enabled or not (-O0 or O3). My current workarround is converting the inline functions to macros which achieves the same effect. Any ideas why inline functions break the code?
    2. Compiler optimizations - well, my project consists of many C files one of which is called flash.c and it contains the main and exported functions. I build the project as follows:
    gcc -c flash.c -O0 -o flash.o     //Please note the -O0 option!!!
    gcc -c file1.c -O3 -o file1.o
    gcc -c file2.c -O3 -o file2.o
    ... and so on
    gcc *.o -swc -O0 -o emu.swc   //Please note the -O0 option again!!!
    mxmlc.exe -library-path+=emu.swc --target-player=10.0.0 Emu.as
    or file in $( ls *.o ) //Removes the obj files
        do
            rm $file
        done
    If I define any option different from -O0 in gcc -c flash.c -O0 -o flash.o the program stops working correctly exactly as in the inline funtions code (but still does not crash or prints any errors in debug). flash has 4 static functions to be exported to AS3 and the main function. Do you know why?
    If I define any option different from -O0 in gcc *.o -swc -O0 -o emu.swc  the program stops working correctly exactly as above, but if I specify -O1, -O2 or O3 the SWC file gets smaller up to 2x for O3. Why? Is there a method to optimize all the obj files except flash.o because I suspect a similar issue as when compilling it?
    3. Flating point issues - this is the worst one. My code is mainly based on integer arithmetic but on 1-2 places it requires flating point arithmetic. One of them is the conversion of 16-bit 44.1 Khz sound buffer to a float buffer with same sample rate but with samples in the range from -1.0 to 1.0.
    My code:
    void audio_prepare_as()
        uint32 i;
        for(i=0;i<audioSamples;i+=2)
            audiobuffer[i] = (float)snd.buffer[i]/32768;
            audiobuffer[i+1] = (float)snd.buffer[i+1]/32768;
    My audio playback is working perfectly. But not if using the above conversion and I have inspected the float numbers - all incorrect and invalid. I tried other code with simple floats - same story. As if alchemy refuses to work with floats. What is wrong? I have another lace whre I must resize the framebuffer and there I have a float involved - same crap. Please help me?
    Found the floating point problem: audiobuffer is written to a ByteArray and then used in AS. But C floats are obviously not the same as those in AS3. Now the floating point is resolved.
    The optimization issues remain! I really need to speed up my code.
    Thank you in advice!

    Dear Bernd,
    I am still unable to run the optimizations and turn on the inline functions. None of the inline functions contain any stdli function just pure asignments, reads, simple arithmetic and bitwise operations.
    In fact, the file containing the main function and those functions for export in AS3 did have memset and memcpy. I tried your suggestion and put the code above the functions calling memset and memcpy. It did not work soe I put the code in a header which is included topmost in each C file. The only system header I use is malloc.h and it is included topmost. In other C file I use pow, sin and log10 from math.h but I removed it and made the same thing:
    //shared.h
    #ifndef _SHARED_H_
    #define _SHARED_H_
    #include <malloc.h>
    static void * custom_memmove( void * destination, const void * source, unsigned int num ) {
      void *result; 
      __asm__("%0 memmove(%1, %2, %3)\n" : "=r"(result) : "r"(destination), "r"(source), "r"(num)); 
      return result; 
    static void * custom_memcpy ( void * destination, const void * source, unsigned int num ) { 
      void *result; 
      __asm__("%0 memcpy(%1, %2, %3)\n" : "=r"(result) : "r"(destination), "r"(source), "r"(num)); 
      return result; 
    static void * custom_memset ( void * ptr, int value, unsigned int num ) { 
      void *result; 
      __asm__("%0 memset(%1, %2, %3)\n" : "=r"(result) : "r"(ptr), "r"(value), "r"(num)); 
      return result; 
    static float custom_pow(float x, int y) {
        float result;
      __asm__("%0 pow(%1, %2)\n" : "=r"(result) : "r"(x), "r"(y));
      return result;
    static double custom_sin(double x) {
        double result;
      __asm__("%0 sin(%1)\n" : "=r"(result) : "r"(x));
      return result;
    static double custom_log10(double x) {
        double result;
      __asm__("%0 log10(%1)\n" : "=r"(result) : "r"(x));
      return result;
    #define memmove custom_memmove
    #define memcpy custom_memcpy
    #define memset custom_memset
    #define pow custom_pow
    #define sin custom_sin
    #define log10 custom_log10 
    #include "types.h"
    #include "macros.h"
    #include "m68k.h"
    #include "z80.h"
    #include "genesis.h"
    #include "vdp.h"
    #include "render.h"
    #include "mem68k.h"
    #include "memz80.h"
    #include "membnk.h"
    #include "memvdp.h"
    #include "system.h"
    #include "loadrom.h"
    #include "input.h"
    #include "io.h"
    #include "sound.h"
    #include "fm.h"
    #include "sn76496.h" 
    #endif /* _SHARED_H_ */ 
    It still behave the same way as if nothing was changed (works incorrectly - displays jerk which does not move, whereby the image is supposed to move)
    As I am porting an emulator (Sega Mega Drive) I use manu arrays of function pointers for implementing the opcodes of the CPU's. Could this be an issue?
    I did a workaround for the floating point problem but processing is very slow so I hear only bzzt bzzt but this is for now out of scope. The emulator compiled with gcc runs at 300 fps on a 1.3 GHz machine, whereby my non optimized AVM2 code compiled by alchemy produces 14 fps. The pure rendering is super fast and the problem lies in the computational power of AVM. The frame buffer and the enulation are generated in the C code and only the pixels are copied to AS3, where they are plotted in a BitmapData. On 2.0 GHz Dual core I achieved only 21 fps. Goal is 60 fps to have smooth audio and video. But this is offtopic. After all everything works (slow) without optimization, and I would somehow turn it on. Suggestions?
    Here is the file with the main function:
    #include "shared.h"
    #include "AS3.h"
    #define FRAMEBUFFER_LENGTH    (320*240*4)
    static uint8* framebuffer;
    static uint32  audioSamples;
    AS3_Val sega_rom(void* self, AS3_Val args)
        int size, offset, i;
        uint8 hardware;
        uint8 country;
        uint8 header[0x200];
        uint8 *ptr;
        AS3_Val length;
        AS3_Val ba;
        AS3_ArrayValue(args, "AS3ValType", &ba);
        country = 0;
        offset = 0;
        length = AS3_GetS(ba, "length");
        size = AS3_IntValue(length);
        ptr = (uint8*)malloc(size);
        AS3_SetS(ba, "position", AS3_Int(0));
        AS3_ByteArray_readBytes(ptr, ba, size);
        //FILE* f = fopen("boris_dump.bin", "wb");
        //fwrite(ptr, size, 1, f);
        //fclose(f);
        if((size / 512) & 1)
            size -= 512;
            offset += 512;
            memcpy(header, ptr, 512);
            for(i = 0; i < (size / 0x4000); i += 1)
                deinterleave_block(ptr + offset + (i * 0x4000));
        memset(cart_rom, 0, 0x400000);
        if(size > 0x400000) size = 0x400000;
        memcpy(cart_rom, ptr + offset, size);
        /* Free allocated file data */
        free(ptr);
        hardware = 0;
        for (i = 0x1f0; i < 0x1ff; i++)
            switch (cart_rom[i]) {
         case 'U':
             hardware |= 4;
             break;
         case 'J':
             hardware |= 1;
             break;
         case 'E':
             hardware |= 8;
             break;
        if (cart_rom[0x1f0] >= '1' && cart_rom[0x1f0] <= '9') {
            hardware = cart_rom[0x1f0] - '0';
        } else if (cart_rom[0x1f0] >= 'A' && cart_rom[0x1f0] <= 'F') {
            hardware = cart_rom[0x1f0] - 'A' + 10;
        if (country) hardware=country; //simple autodetect override
        //From PicoDrive
        if (hardware&8)        
            hw=0xc0; vdp_pal=1;
        } // Europe
        else if (hardware&4)    
            hw=0x80; vdp_pal=0;
        } // USA
        else if (hardware&2)    
            hw=0x40; vdp_pal=1;
        } // Japan PAL
        else if (hardware&1)      
            hw=0x00; vdp_pal=0;
        } // Japan NTSC
        else
            hw=0x80; // USA
        if (vdp_pal) {
            vdp_rate = 50;
            lines_per_frame = 312;
        } else {
            vdp_rate = 60;
            lines_per_frame = 262;
        /*SRAM*/   
        if(cart_rom[0x1b1] == 'A' && cart_rom[0x1b0] == 'R')
            save_start = cart_rom[0x1b4] << 24 | cart_rom[0x1b5] << 16 |
                cart_rom[0x1b6] << 8  | cart_rom[0x1b7] << 0;
            save_len = cart_rom[0x1b8] << 24 | cart_rom[0x1b9] << 16 |
                cart_rom[0x1ba] << 8  | cart_rom[0x1bb] << 0;
            // Make sure start is even, end is odd, for alignment
            // A ROM that I came across had the start and end bytes of
            // the save ram the same and wouldn't work.  Fix this as seen
            // fit, I know it could probably use some work. [PKH]
            if(save_start != save_len)
                if(save_start & 1) --save_start;
                if(!(save_len & 1)) ++save_len;
                save_len -= (save_start - 1);
                saveram = (unsigned char*)malloc(save_len);
                // If save RAM does not overlap main ROM, set it active by default since
                // a few games can't manage to properly switch it on/off.
                if(save_start >= (unsigned)size)
                    save_active = 1;
            else
                save_start = save_len = 0;
                saveram = NULL;
        else
            save_start = save_len = 0;
            saveram = NULL;
        return AS3_Int(0);
    AS3_Val sega_init(void* self, AS3_Val args)
        system_init();
        audioSamples = (44100 / vdp_rate)*2;
        framebuffer = (uint8*)malloc(FRAMEBUFFER_LENGTH);
        return AS3_Int(vdp_rate);
    AS3_Val sega_reset(void* self, AS3_Val args)
        system_reset();
        return AS3_Int(0);
    AS3_Val sega_frame(void* self, AS3_Val args)
        uint32 width;
        uint32 height;
        uint32 x, y;
        uint32 di, si, r;
        uint16 p;
        AS3_Val fb_ba;
        AS3_ArrayValue(args, "AS3ValType", &fb_ba);
        system_frame(0);
        AS3_SetS(fb_ba, "position", AS3_Int(0));
        width = (reg[12] & 1) ? 320 : 256;
        height = (reg[1] & 8) ? 240 : 224;
        for(y=0;y<240;y++)
            for(x=0;x<320;x++)
                di = 1280*y + x<<2;
                si = (y << 10) + ((x + bitmap.viewport.x) << 1);
                p = *((uint16*)(bitmap.data + si));
                framebuffer[di + 3] = (uint8)((p & 0x1f) << 3);
                framebuffer[di + 2] = (uint8)(((p >> 5) & 0x1f) << 3);
                framebuffer[di + 1] = (uint8)(((p >> 10) & 0x1f) << 3);
        AS3_ByteArray_writeBytes(fb_ba, framebuffer, FRAMEBUFFER_LENGTH);
        AS3_SetS(fb_ba, "position", AS3_Int(0));
        r = (width << 16) | height;
        return AS3_Int(r);
    AS3_Val sega_audio(void* self, AS3_Val args)
        AS3_Val ab_ba;
        AS3_ArrayValue(args, "AS3ValType", &ab_ba);
        AS3_SetS(ab_ba, "position", AS3_Int(0));
        AS3_ByteArray_writeBytes(ab_ba, snd.buffer, audioSamples*sizeof(int16));
        AS3_SetS(ab_ba, "position", AS3_Int(0));
        return AS3_Int(0);
    int main()
        AS3_Val romMethod = AS3_Function(NULL, sega_rom);
        AS3_Val initMethod = AS3_Function(NULL, sega_init);
        AS3_Val resetMethod = AS3_Function(NULL, sega_reset);
        AS3_Val frameMethod = AS3_Function(NULL, sega_frame);
        AS3_Val audioMethod = AS3_Function(NULL, sega_audio);
        // construct an object that holds references to the functions
        AS3_Val result = AS3_Object("sega_rom: AS3ValType, sega_init: AS3ValType, sega_reset: AS3ValType, sega_frame: AS3ValType, sega_audio: AS3ValType",
            romMethod, initMethod, resetMethod, frameMethod, audioMethod);
        // Release
        AS3_Release(romMethod);
        AS3_Release(initMethod);
        AS3_Release(resetMethod);
        AS3_Release(frameMethod);
        AS3_Release(audioMethod);
        // notify that we initialized -- THIS DOES NOT RETURN!
        AS3_LibInit(result);
        // should never get here!
        return 0;

  • Using bigdecimal class

    I was using Gregory-Leibniz series to calculate PI = 4 - 4/3 + 4/5 - 4/7 + 4/9 - 4/11 + ...
    Something like:
    double pi = 0.0;      
           int limit = 3000000;      
           for (int i = 0, y = 1; i <= limit; y+=2, i++)
                     if (y == 1)
                          pi = 4;
                   else if (i % 2 == 0)
                          pi += (double)4/y;            
                     else
                          pi -= (double)4/y;                                                   
                     System.out.println(String.format("Loop %d: %.20f", i, pi));                                    }Then I realized PI isn't going to be totally accurate according to IEEE Standard for Binary Floating-Point Arithmetic that java math calculation uses, so I was trying to use BigDecimal class (new to me), this is what I got initally...
             BigDecimal pi = new BigDecimal("0.00");           
              int limit = 3000000;
              for (int i = 0, y = 1; i <= limit; y += 2, i++)
                  if (y == 1)
                          pi = new BigDecimal("4.0");
                   else if (i % 2 == 0)
                          pi = pi.add(new BigDecimal( Double.toString( (double) 4 / y )));
                     else
                          pi = pi.subtract(new BigDecimal( Double.toString( (double) 4 / y )));
                        System.out.println(String.format("Loop %d: %s", i, pi.toString()));                                       
    I realize that when I do the 4/y calculations involving both doubles... the result is probably stored according to the IEEE standards which is the thing to avoid... Is that correct? Is my PI result going to be accurate?
    I noticed with this one decimals up to the 22nd place are all filled with some numbers in the calculations compared with the first one involving only double number calculations which had zero's starting around the 15th decimal.
    Something like doesn't work and ends up with arithmeticexceptions...
    pi = pi.subtract(new BigDecimal("4").divide(new BigDecimal(Integer.toString(y))));
    So I'm actually confused about the right way of using BigDecimal class in this type of calculation to get accurate results. I do realize it's an immutable class and probably a bad idea to use it like this 3 million times in a loop.

    quoting from the API documentation on BigDecimal
    "The BigDecimal class gives its user complete control over rounding behavior. If no rounding mode is specified and the exact result cannot be represented, an exception is thrown; otherwise, calculations can be carried out to a chosen precision and rounding mode by supplying an appropriate MathContext object to the operation."
    That explains the arithmetic exceptions.
    You would be advised to choose your scale first, (that would be the number of decimal places that you want to be using for your calculation. ) Then use the BigDecimal constructors that use the scale value. Construct your BigDecimal 4 outside of the loop so that you are not constructing it over and over again. And finally, read the documentation on how the scale of the result will depend upon the scale of the components going in.
    A little reading and possibly re-reading of the documentation will help in the understanding of the BigDecimal class.

  • Using Modulus (%) arithmetic operator with decimals

    When trying to use the arithmetic operator modulus with decimals there seem to be some errors in the results. Is there a restriction on the number/value of decimals that can be used with this operator? Am I perhaps just using it incorrectly?
    example ...
    Double valA= new Double("12.4");
    Double valB = new Double("1236");
    double result = valB.floatValue() % valA.floatValue();
    System.out.println("valB : " + valB );
    System.out.println("valA: " + valA);
    System.out.println("result : " + result);
    produces :
    valB : 1236.0
    valA : 12.4
    result : 8.40003776550293
    But :
    Double valA= new Double("12.5");
    Double valB = new Double("1236");
    double result = valB.floatValue() % valA.floatValue();
    System.out.println("valB : " + valB );
    System.out.println("valA: " + valA);
    System.out.println("result : " + result);
    produces :
    valB : 1236.0
    valA : 12.5
    result : 11.0

    Floating point arithmetic in general is not exact. The problem is that you are expecting exact results.
    In the second example where you use 12.5 and 1236.0 is just so happens that both of those numbers can be represented exactly, so you do get an exact result.

  • Infix to postfix printing out incorrectly sometimes..any ideas?

    alright, my program this time is to make an infix to postfix converter.
    I have it coded, and it works fine except when I use parenthesis. I'm supposed to test it with these expressions:
    a + b
    a * b + c
    a * ( b + c )
    a + b * c - d
    ( a + b ) * ( c - d )
    a - ( b - ( v - ( d - ( e - f ))))
         // initialize two stacks: operator and operand
         private Stack operatorStack = new Stack();
         private Stack operandStack = new Stack();
         // method converts infix expression to postfix notation
         public String toPostfix(String infix)
              StringTokenizer s = new StringTokenizer(infix);
              // divides the input into tokens for input
              String symbol, postfix = "";
              while (s.hasMoreTokens())
              // while there is input to be read
                   symbol = s.nextToken();
                   // if it's a number, add it to the string
                   if (Character.isDigit(symbol.charAt(0)))
                        postfix = postfix + " " + (Integer.parseInt(symbol));
                   else if (symbol.equals("("))
                   // push "("
                        Character operator = new Character('(');
                        operatorStack.push(operator);
                   else if (symbol.equals(")"))
                   // push everything back to "("
                        /** ERROR OCCURS HERE !!!! **/
                                 while (((Character)operatorStack.peek()).charValue() != '(')
                             postfix = postfix + " " + operatorStack.pop();
                        operatorStack.pop();
                   else
                   // print operatorStack occurring before it that have greater precedence
                        while (!operatorStack.isEmpty() && !(operatorStack.peek()).equals("(") && prec(symbol.charAt(0)) <= prec(((Character)operatorStack.peek()).charValue()))
                             postfix = postfix + " " + operatorStack.pop();
                        Character operator = new Character(symbol.charAt(0));
                        operatorStack.push(operator);
              while (!operatorStack.isEmpty())
                   postfix = postfix + " " + operatorStack.pop();
              return postfix;
    // method compares operators to establish precedence
         public int prec(char x)
              if (x == '+' || x == '-')
                   return 1;
              if (x == '*' || x == '/' || x == '%')
                   return 2;
              return 3;
    /** MY STACK **/
    import java.util.LinkedList;
    public class StackL {
      private LinkedList list = new LinkedList();
      public void push(Object v) {
        list.addFirst(v);
      public Object peek() {
        return list.getFirst();
      public Object pop() {
        return list.removeFirst();
      public boolean isEmpty()
          return (list.size() == 0);
    }weird, it erased my question/errors I put in...
    When I use any of the expressions with parenthesis (except the 2nd to last one) I get an emptystackexception pointing to the area noted in the code.
    When I test the 2nd to last one (the one I would expect it to give me the most trouble) it prints out an answer, but it is incorrect. It prints out this : "Expression in postfix: a ( b - ( c - ( d - ( e - f ) -" which is incorrect, as it hsould have no parenthesis
    Edited by: Taco_John on Apr 6, 2008 12:46 PM
    Edited by: Taco_John on Apr 6, 2008 12:47 PM
    Edited by: Taco_John on Apr 6, 2008 12:49 PM

    the algorithm we were told to use is here:
    While not stack error and not the end of infix expression
    a.) Extract the next input token from the infix expression (can be constant value, variable, arithmetic operator, left or right parenthesis)
    b.) If token is
    - left parenthesis : push it onto the stack
    - right parenthesis : pop and display stack elements until the left parenthesis is popped (don't sisplay right parenthesis). It's an error if stack becomes empty with no matching right parenthesis found.
    - Operator : if the stack is empty or token is higher priority than the top element, push it onto the stack. Otherwise, pop and display the top stack element and repeat comparison of token with new top element
    Note : left parenthesis in the stack is assumed to have a lower priority than any operator.
    - operand : display it
    When the end of the infix expression is reached, pop and display remaining stack elements until it is empty.
    it works fine on anything without a parenthesis, and it prints an answer (however it is incorrect) for the a - (b-(c-(d-(e-f)))) expression.
    still looking for an idea if I can get one
    Ok, I just noticed this. If i do a * ( b + c ) I get the error. But if I type " a * ( ( b + c ))" with spaces between the left parenthesis and adding an extra parenthesis as well, and NOT spacing the right parenthesis, I get a result that works just like that 2nd to last was doing. So it's something about the spaces...The answer is incorrect when I use the parenthesis as well. So it's not ignoring white space correctly for some reason and it's printing incorrect answers when I use parenthesis.

  • GL_Cancelled_Date displaying incorrect year

    I currently have around 560 rows of bad data where GL_Encumbered_Date and TO_CHAR(PRD.GL_ENCUMBERED_DATE,'YYYY'  display correctly. The problem lies in PRD.GL_CANCELLED_DATE which displays correctly (example: 30-APR-10) but TO_CHAR(PRD.GL_CANCELLED_DATE, 'DD-MON-YYYY') for the same row displays as 30-APR-0010.
    I have separated out the incorrect year with: to_char(prd.gl_cancelled_date,'YYYY') where each of the 560 rows display 0010 instead of 2010.
    I am unsure if arithmetic with dates is allowed within SQL- but am curious if the operation date + number will result in a date. If this is so, how could one go about taking 0010 as a date and add 2000 to create 2010 for: PRD.GL_CANCELLED_DATE.

    i don't understand .. what is the problem :
    SQL> alter session set nls_date_format = 'dd-mon-yy';
    Session altered.
    SQL> select TO_date('30-APR-10', 'DD-MON-YY') from dual;
    TO_DATE('
    30-apr-10
    SQL> alter session set nls_date_format = 'dd-mon-yyyy';
    Session altered.
    SQL> select TO_date('30-APR-10', 'DD-MON-YY') from dual;
    TO_DATE('30
    30-apr-2010
    SQL>

  • UDF for BigDecimal Sum

    Hi All,
    I have to sum all of my amount values in Detail Records. I want to use BigDecimal in UDF because if I use the standard sum, the precision is going to be more than 4 digits. So if we use BigDecimal then I will get the exact result. Can anyone please help me for writing the UDF for getting the sum of all my numbers using BigDecimal.
    Your inputs are highly appreciated.
    Cheers,
    korobee

    Hi,
    Refer this Blog <a href="/people/thorsten.nordholmsbirk/blog/2006/08/25/new-arithmetic-and-statistical-functions-in-message-mappings-in-sp18 Arithmetic and Statistical Functions in Message Mappings in SP18</a>.
    Following is the code to add two numbers using BigDecimal.
    String add(String a, String b)
      BigDecimal bigA = new BigDecimal(a);
      BigDecimal bigB = new BigDecimal(b);
      BigDecimal bigSum = bigA.add(bigB);
      return bigSum.toString();
    Refer: Blog
    Thanks,
    SaNv...

  • Incorrect arguments to mysql_stmt_execute

    Hi there,
    i'm spending 2 days by trying to solve an apparently stupid problem:
    I'm using DataProvider and RowSet in a simple jsf page. The table I want to update is composed by 3 FK and 1PK(auto-increment). DBMS=MySQL.
    I can insert without problems by using setInsertableColumns.
    The problem arises when I try to update. This is the code:
    !!!! CODE snippet !!!!
    CachedRowSetX crs = (CachedRowSetX)listino_dettaglioDataProvider.getCachedRowSet();
    crs.setUpdatableColumns( new boolean[] { true, true, true, true,false } ) ;
    mDataProvider.setValue("t.PRO_ID",id,proid); // FK field
    ...toher FKs...
    mDataProvider.setValue("t.PRICE",id,price); // simple field
    ...NO PK setting...just row update...
    mDataProvider.commitChanges();
    !!!THIS the ERROR:!!!
    Number of conflicts while synchronizing: 1 SyncResolver.UPDATE_ROW_CONFLICT row 1 Incorrect arguments to mysql_stmt_execute
    !!!THIS IS PRINTSTATEMENTS OUTPUT!!!!
    INSERT INTO dbmultisite2.t (PRO_ID, PRICE, FAS_ID, LIS_ID) VALUES (?, ?, ?, ?)
    SELECT PRO_ID, PRICE, FAS_ID, LIS_ID, LISDET_ID FROM dbmultisite2.t WHERE PRO_ID = ? AND PRICE = ? AND FAS_ID = ? AND LIS_ID = ? AND LISDET_ID = ?
    Paramm[1]=(java.lang.Integer,1) Paramm[2]=(java.math.BigDecimal,0.10) Paramm[3]=(java.lang.Integer,12155) Paramm[4]=(java.lang.Integer,17) Paramm[5]=(java.lang.Integer,21)
    Writer: executing pre-update SELECT
    !!!! END !!!!
    so my questions are:
    - why INSERT????
    - what argument is incorrect?? I ask this because when you go wrong this a column the jdbc says "ColsXYZ error...." but, in this case, the stmt is wrong but no more info I can get.
    - I used the same approce with other tables with/out FKs,PK and I have no problem...
    can some1 give me an explanation?
    tnx
    michelangelo

    solved.
    the question is mysql related. downalod last mysql-jdbc-driver
    no jsf problem... :)..fortunately
    michelangelo

  • Incorrect result of "neg" function

    Hello! I'm using neg function in my mapping. In some cases, it works incorrect. For example:
    In: 140132.04
    Out: -140132.05
    why? and what should I do?

    Hi,
    you could set
    com.sap.aii.mappingtool.flib3.bigdecimalarithmetic = true
    in exchange profile.
    It's explained here:
    /people/thorsten.nordholmsbirk/blog/2006/08/25/new-arithmetic-and-statistical-functions-in-message-mappings-in-sp18
    Regards
    Patrick

Maybe you are looking for