c - C 中奇怪的计算问题乘以 1.2 失败

标签 c casting

我有这个 C 代码,我需要从一个 long 计算一个 dobule。

double result;
long t2_value;

t2_value = 72;
result = t2_value * 1.2;

现在这段代码在“result = t2_value * 1.2;”处崩溃只有错误“Vector 0000000006”。

奇怪的是,如果我替换

result = t2_value * 1.2;

result = 72 * 1.2;

evything 正常工作,我已经尝试将 t2_value 类型转换为 double

result = ((double)t2_value * 1.2);

或者将其设为 int 而不是 long,但没有任何帮助。

所有代码,见main方法 /*!\文件 *\brief 第一个用户程序 - * */

#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");
        }
    }
}

制作文件

# 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

这里是 prints 和 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]="0123456789abcdef";
 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]);
 }
}

最佳答案

Ignacio Vazquez-Abrams 的评论可能说到了点子上。由于这不是标准环境,您知道甚至支持浮点运算吗?它们真的有必要或可取吗?您很可能会从以下方面获得可接受的结果:

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/10 为单位的值。

关于c - C 中奇怪的计算问题乘以 1.2 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2796931/

相关文章:

c - 有右引力标记的例子吗?

c++ - Arduino循环/设置问题

C语言比较链表中的chararrays

c - 安西C :Is an array's name Stored as a pointer variable?

java - 在 OSX 上的 Java 中从大的 long 转换为 float 时出现错误?

casting - NSDictionary objectForKey 运行时错误的 stringValue

ios - 如何在 Swift 中将 UIViewController 转换或类型转换为 AnyClass

java - 在 Java 中通过 UDP 发送 C++ 结构

c++ - 这个 Actor 分配了什么? C风格选角

c - 有没有办法证明对int的积分提升?