2010-05-09 39 views
1

我有這個C代碼,在那裏我需要計算一個長的dobule。C中奇怪的計算問題乘以1.2失敗

double result; 
long t2_value; 

t2_value = 72; 
result = t2_value * 1.2; 

現在,這個代碼在崩潰 「結果= t2_value * 1.2;」只有錯誤「Vector 0000000006」。

這是很奇怪的,如果我更換

result = t2_value * 1.2; 

result = 72 * 1.2; 

evything工作只是因爲它應該,我已經tryed型鑄造t2_value作爲雙

result = ((double)t2_value * 1.2); 

或使它成爲一個長整型,但沒有什麼幫助。

所有代碼,請參閱主要方法 /*! \文件 * \介紹的第一個用戶程序 - * */

#include <scwrapper.h> 


long thread_1_empty_semaphore_handle; 
long thread_1_mutex_semaphore_handle; 
long thread_1_full_semaphore_handle; 
long thread_2_empty_semaphore_handle; 
long thread_2_mutex_semaphore_handle; 
long thread_2_full_semaphore_handle; 

int debug; 

long value_thread_1; 
long value_thread_2; 


long send_port; 

void thread_1(void) 
{ 
    while(1) 
    { 
     long value; 

     if (ALL_OK != semaphoredown(thread_1_full_semaphore_handle)) 
      break; 

     if (ALL_OK != semaphoredown(thread_1_mutex_semaphore_handle)) 
      break; 

     // Generating some random number here and save it in value_thread_1 
     value_thread_1 = 91; 
     if(debug == 1) prints("Writing thread 1!\n"); 

     if (ALL_OK != semaphoreup(thread_1_mutex_semaphore_handle)) 
      break; 

     if (ALL_OK != semaphoreup(thread_1_empty_semaphore_handle)) 
      break; 
    } 
    terminate(); 
} 
void thread_2(void) 
{ 
    while(1) 
    { 
     long value; 

     if (ALL_OK != semaphoredown(thread_2_full_semaphore_handle)) 
      break; 

     if (ALL_OK != semaphoredown(thread_2_mutex_semaphore_handle)) 
      break; 

     // Generating some random number here and save it in value_thread_1 
     value_thread_2 = 72; 
     if(debug == 1) prints("Writing thread 2!\n"); 

     if (ALL_OK != semaphoreup(thread_2_mutex_semaphore_handle)) 
      break; 

     if (ALL_OK != semaphoreup(thread_2_empty_semaphore_handle)) 
      break; 
    } 
    terminate(); 
} 

int create_thread_1() 
{ 
    if(debug == 1) 
     prints("Creating thread 1!\n"); 
    register long thread_stack; 
    thread_1_empty_semaphore_handle=createsemaphore(16); 
    if (thread_1_empty_semaphore_handle<0) 
     return -1; 
    thread_1_full_semaphore_handle=createsemaphore(0); 
    if (thread_1_full_semaphore_handle<0) 
     return -1; 
    thread_1_mutex_semaphore_handle=createsemaphore(1); 
    if (thread_1_mutex_semaphore_handle<0) 
     return -1; 
    thread_stack=alloc(4096, 0); 
    if (0 >= thread_stack) 
     return -1; 
    if (ALL_OK != createthread(thread_1, thread_stack+4096)) 
     return -1; 
    return 1; 
} 
long read_tread_1() 
{ 
    long value = 0; 

    if (ALL_OK != semaphoredown(thread_1_empty_semaphore_handle)) 
     return -1; 

    if (ALL_OK != semaphoredown(thread_1_mutex_semaphore_handle)) 
     return -1; 

    value = value_thread_1; 
    if(debug == 1) 
     prints("Reading thread 1!\n"); 

    if (ALL_OK != semaphoreup(thread_1_mutex_semaphore_handle)) 
     return -1; 

    if (ALL_OK != semaphoreup(thread_1_full_semaphore_handle)) 
     return -1; 

    return value; 
} 

int create_thread_2() 
{ 
    if(debug == 1) 
     prints("Creating thread 2!\n"); 
    register long thread_stack; 
    thread_2_empty_semaphore_handle=createsemaphore(16); 
    if (thread_2_empty_semaphore_handle<0) 
     return -1; 
    thread_2_full_semaphore_handle=createsemaphore(0); 
    if (thread_2_full_semaphore_handle<0) 
     return -1; 
    thread_2_mutex_semaphore_handle=createsemaphore(1); 
    if (thread_2_mutex_semaphore_handle<0) 
     return -1; 
    thread_stack=alloc(4096, 0); 
    if (0 >= thread_stack) 
     return -1; 
    if (ALL_OK != createthread(thread_2, thread_stack+4096)) 
     return -1; 
    return 1; 
} 
long read_tread_2() 
{ 
    long value = 0; 

    if (ALL_OK != semaphoredown(thread_2_empty_semaphore_handle)) 
     return -1; 

    if (ALL_OK != semaphoredown(thread_2_mutex_semaphore_handle)) 
     return -1; 

    value = value_thread_2; 
    if(debug == 1) 
     prints("Reading thread 2!\n"); 

    if (ALL_OK != semaphoreup(thread_2_mutex_semaphore_handle)) 
     return -1; 

    if (ALL_OK != semaphoreup(thread_2_full_semaphore_handle)) 
     return -1; 

    return value; 
} 

int send_message(double message) 
{ 
    struct message msg; 

    if(debug == 1) 
     prints("Canculation message"); 
    // We are multiplying the integer with 1000, and thorws all the decimals away 
    long temp = (long)(message * 1000.0); 
    msg.quad_0 = temp; 
    msg.quad_1 = 0; 
    msg.quad_2=0; 
    msg.quad_3=0; 
    msg.quad_4=0; 
    msg.quad_5=0; 
    msg.quad_6=0; 
    msg.quad_7=0; 

    prints("0: "); 
    printhex(msg.quad_0); 
    prints("\n"); 
    prints("1: "); 
    printhex(msg.quad_1); 
    prints("\n"); 

    if (ALL_OK != send(send_port, &msg)) 
     return -1; 
    return 1; 
} 
void administrat_medicin(double amount) 
{ 
} 

void 
    main(int argc, char* argv[]) 
{ 
    debug = 0; 
    long my_pid = getpid(); 

    create_thread_1(); 
    create_thread_2(); 

    /* Launch instances of program_1 */ 
    if (ALL_OK != createprocess(1)) 
    { 
     if(debug == 1) 
      prints("Unable to launch program 1 in a new process\n"); 
     debugger(); 
    } 

    // Finding a send port 
    send_port = findport(0,1); 
    if (send_port < 0) 
    { 
     if(debug == 1) 
      prints("process 1: finding a send port in process 0 failed\n"); 
     terminate(); 
    } 

    /* This is the producer. */ 
    long t1_value; // Puls 
    long t2_value; // Blod sugar 
    double result; 
    double ration = 1.2; 
    while(1) 
    { 
     t1_value = read_tread_1(); 
     if(-1 == t1_value) 
     { 
      if(debug == 1) 
       prints("Error reading t1"); 
      break; 
     } 

     t2_value = read_tread_2(); 
     if(-1 == t2_value) 
     { 
      if(debug == 1) 
       prints("Error reading t2"); 
      break; 
     } 

     // If there are no date yet, no point in sending it 
     // This will also skip if there are no pulse 
     if(t1_value > 0 && t2_value > 0) 
     { 
      // Calculate the medicine to give. 
      prints("Calculating\n"); 
      result = (t2_value * ration); 
      prints("Result: "); 
      printhex(result); 
      prints("\n"); 

      if(debug == 1) 
       prints("Sending message\n"); 
      if(-1 == send_message(result)) 
      { 
       if(debug == 1) 
       prints("Message send failed"); 
      } 
      if(debug == 1) 
       prints("Message sendt"); 
     } 
    } 
} 

Make文件

# The following line holds compiler options 
CFLAGS = -fno-exceptions -fno-common -Isrc/include 

# Do not change the following line. You will not be able to compile without it 
PREFIX := "${PWD}/../../support_software/bin/bin" 

bochs_boot: boot/kernel 
    ${PREFIX}/genext2fs -b 1440 -d boot bochs_stuff/b.img 
    (cd bochs_stuff; nice -20 ${PREFIX}/bochs) 

kernel: boot/kernel 

src/include/scwrapper.h: src/include/sysdefines.h 

src/kernel/kernel.h: src/include/sysdefines.h 

boot/kernel: objects/kernel/boot32.o objects/kernel/boot64.o objects/kernel/enter.o src/kernel/kernel_link.ld objects/program_0/executable.o objects/program_1/executable.o objects/program_2/executable.o binary_kernel/binary_kernel.o 
    ${PREFIX}/x86_64-pc-elf-ld --no-warn-mismatch -Tsrc/kernel/binary_kernel_link.ld -o boot/kernel objects/kernel/boot32.o objects/kernel/boot64.o objects/kernel/enter.o binary_kernel/binary_kernel.o objects/program_0/executable.o objects/program_1/executable.o objects/program_2/executable.o 

objects/kernel/boot32.o: src/kernel/boot32.s 
    ${PREFIX}/x86_64-pc-elf-as --32 -o objects/kernel/boot32.o src/kernel/boot32.s 

objects/kernel/boot64.o: src/kernel/boot64.s 
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/kernel/boot64.o src/kernel/boot64.s 

objects/kernel/enter.o: src/kernel/enter.s 
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/kernel/enter.o src/kernel/enter.s 

objects/program_startup_code/startup.o: src/program_startup_code/startup.s 
    ${PREFIX}/x86_64-pc-elf-as --64 -o objects/program_startup_code/startup.o src/program_startup_code/startup.s 

objects/program_0/main.o: src/program_0/main.c src/include/scwrapper.h 
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_0/main.o src/program_0/main.c 

objects/program_0/executable: objects/program_startup_code/startup.o objects/program_0/main.o 
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_0/executable objects/program_startup_code/startup.o objects/program_0/main.o 

objects/program_0/executable.o: objects/program_0/executable 
    ${PREFIX}/x86_64-pc-elf-strip objects/program_0/executable 
    ${PREFIX}/x86_64-pc-elf-objcopy -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_0/executable objects/program_0/executable.o 

objects/program_1/main.o: src/program_1/main.c src/include/scwrapper.h 
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_1/main.o src/program_1/main.c 

objects/program_1/executable: objects/program_startup_code/startup.o objects/program_1/main.o 
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_1/executable objects/program_startup_code/startup.o objects/program_1/main.o 

objects/program_1/executable.o: objects/program_1/executable 
    ${PREFIX}/x86_64-pc-elf-strip objects/program_1/executable 
    ${PREFIX}/x86_64-pc-elf-objcopy -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_1/executable objects/program_1/executable.o 

objects/program_2/main.o: src/program_2/main.c src/include/scwrapper.h 
    ${PREFIX}/x86_64-pc-elf-gcc -fPIE -m64 $(CFLAGS) -c -O3 -o objects/program_2/main.o src/program_2/main.c 

objects/program_2/executable: objects/program_startup_code/startup.o objects/program_2/main.o 
    ${PREFIX}/x86_64-pc-elf-ld -static -Tsrc/program_startup_code/program_link.ld -o objects/program_2/executable objects/program_startup_code/startup.o objects/program_2/main.o 

objects/program_2/executable.o: objects/program_2/executable 
    ${PREFIX}/x86_64-pc-elf-strip objects/program_2/executable 
    ${PREFIX}/x86_64-pc-elf-objcopy -I binary -O elf32-i386 -B i386 --set-section-flags .data=alloc,contents,load,readonly,data objects/program_2/executable objects/program_2/executable.o 

clean: 
    -rm -rf objects 
    -rm boot/kernel 
    -rm bochs_stuff/b.img 
    mkdir objects 
    mkdir objects/kernel 
    mkdir objects/program_startup_code 
    mkdir objects/program_0 
    mkdir objects/program_1 
    mkdir objects/program_2 

compile: boot/kernel 

這裏是版畫和printhex 無效

prints(const char* string) 
{ 
/* Loop until we have found the null character. */ 
while(1) 
{ 
    register const char curr = *string++; 

    if (curr) 
    { 
    outb(0xe9, curr); 
    } 
    else 
    { 
    return; 
    } 
} 
} 

void 
printhex(const register long value) 
{ 
const static char hex_helper[16]="abcdef"; 
register int  i; 

/* Print each character of the hexadecimal number. This is a very inefficient 
    way of printing hexadecimal numbers. It is, however, very compact in terms 
    of the number of source code lines. */ 
for(i=15; i>=0; i--) 
{ 
    outb(0xe9, hex_helper[(value>>(i*4))&15]); 
} 
} 
+0

這真的是你遇到的確切代碼嗎?你正在聲明'long t2_value'兩次,這會給編譯器帶來錯誤。你有沒有試過這個確切的代碼片段與描述的結果? – 2010-05-09 07:23:07

+1

你需要發佈實際的代碼*和*陳述你正在使用的編譯器等。 – 2010-05-09 07:28:34

+0

我不知道,因爲我通常不做c代碼,但我認爲編譯器被稱爲「bochs」 – Androme 2010-05-09 07:33:43

回答

2

伊格納西奧巴斯克斯 - 艾布拉姆斯的評論可能會觸及一些事情。由於這不是一個標準環境,你知道甚至支持浮點運算嗎?他們真的有必要嗎?您將最有可能從得到滿意的結果:

long result;  // integer type 
long t2_value; 

t2_value = 72; 
result = ((t2_value * 10) * 12)/100 ; // result = 86 

如果您需要更多顯著的數字,然後例如:

result = ((t2_value * 100) * 120)/1000 ; // result = 864 

這裏result是在現實世界單位的1 /一個十分之值。

+0

謝謝這個工作像魅力,你必須是正確的,該系統不支持浮點運算。 – Androme 2010-05-09 08:21:37

0

我在這裏冒險一個猜測,但我非常確定SSE指令在大多數內核中是不被允許的(如果我沒有記錯的話可以有一個配置選項來允許它)。即使不使用數據向量,編譯器通常會使用SSE擴展來執行浮點計算。嘗試將-mno-sse(或任何與編譯器等效的內容)添加到Makefile標誌中。