我需要一些帮助来编程。 我必须编写一个程序,它可以在没有操作符的情况下进行分频和乘法,并且包含IEEE 754标准。我只能使用+, - ,否定和逻辑运算。需要从文件中读取数字和运算符。
到目前为止,我得到了这个,但它无法正常工作。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
float mult(float a, float b) {
float i = 0;
float c = 0;
while (i < b) {
c = c + a;
i++;
}
return c;
}
//this will be needed to divide
float product=1,multiplier=2,a=1;
int steps=0;
void divCore(float number, float divideBy,float lastDivison)
{
steps++;
if(number - divideBy <
return;
else
{
lastDivison = divideBy;
divideBy *= multiplier;
if(number >= divideBy)
{
product *= multiplier;
divCore(number,divideBy,lastDivison);
}
else
{
a *= 0.5;
multiplier = 1 + a;
divCore(number,lastDivison,lastDivison);
}
}
}
//its an other function for division ,you use this in main
float Divide(float numerator, float denominator)
{
//init data
int neg=(numerator<0)?-1:1;
neg*=(denominator<0)?-1:1;
product = 1;
multiplier = 2;
a = 1;
steps =0;
divCore(abs(numerator),abs(denominator),0);
return product*neg;
}
int main()
{
float i,j;
char c[2];
FILE *in=fopen("input.txt","r");
fscanf(in,"%f",&i);
fscanf(in,"%s",c);
fscanf(in,"%f",&j);
if(strcmp(c,"*")==0){
float a = mult(i,j);
printf("%f\n", a);
}
if(strcmp(c,"/")==0){
float a2 = Divide(i,j);
printf("%f\n", a2);
}
getchar();
getchar();
}
文件看起来像这样(我认为数字不算):
0x0000C942
*
0x0000C942
答案 0 :(得分:2)
只是为了好玩(所以不要请求downvote)。此代码遵守任务中提供的规则;-) ie。不使用C除法(/)或乘法(*)运算符:
float mult(float a, float b)
{
float m;
_asm
{
fld a
fld b
fmul
fstp m
}
return m;
}
float div(float numerator, float denominator)
{
float d;
_asm
{
fld numerator
fld denominator
fdiv
fstp d
}
return d;
}
由于此处没有人提供解决方案是乘法(仅标准化):
float mul(float a, float b)
{
// for normalized floats only
unsigned int a_bits = *((unsigned int*)&a);
unsigned int b_bits = *((unsigned int*)&b);
// hints (* means 'any value')
// ------------------------------------
// sign | exp_bits | coeff_bits | value
// ------------------------------------
// 0 | 0 | 0 | +0.0
// 1 | 0 | 0 | -0.0
// ------------------------------------
// * | 0 | !0 | we'll not handle denormalized here
// * |0x01-0xFE | * | (-1)^s * 1.coeff * 2^(exp_val-127)
// ------------------------------------
// 0 | 0xFF | 0 | +Inf 0x7F800000
// 1 | 0xFF | 0 | -Inf 0xFF800000
// ------------------------------------
// * | 0xFF | !0 | NaN for example 0x7FFFFFFF (8388607 NaN representations)
// ------------------------------------
// if bits 0..30 are 0 (ie. both exp and coeff bits are all 0)
// then our number is zero and multiplication result is zero
if ( ((a_bits << 1) == 0) || ((b_bits << 1) == 0)) // << 1 clears sign bit
{
return 0.0;
}
int a_exp_bits = (a_bits >> 23) & 0xFF;
int b_exp_bits = (b_bits >> 23) & 0xFF;
// when exp bits are 0xFF = value may be +-Inf or Nan so result is NaN too
if ( (a_exp_bits == 0xF) || (b_exp_bits == 0xF))
{
unsigned int NaN = ~(1 << 31); // this is one of 8388607 NaN representations
return *((float*)&NaN);
}
int a_exp_val = a_exp_bits - 127;
int b_exp_val = b_exp_bits - 127;
int a_coeff_bits = a_bits & ((1 << 24) - 1);
int b_coeff_bits = b_bits & ((1 << 24) - 1);
// let's multiply
unsigned long long a24 = (unsigned long long)a_coeff_bits | (1LL << 23); // add implicit 24th bit
unsigned long long b24 = (unsigned long long)b_coeff_bits | (1LL << 23); // add implicit 24th bit
unsigned long long c = 0;
// perform regular multiplication
for(int bit = 0; bit < 24; bit++)
{
if (a24 & (1LL<<bit))
{
c += b24 << bit;
}
}
// result can be 47 or 48 bit wide ie (and have 46th or 47th bit set)
// shift coefficient/significand to the right place
if (c & (1LL << 47))
{
c >>= 47 - 23;
}
else if (c & (1LL << 46))
{
c >>= 46 - 23;
}
c &= ~(1<<23); // clear 24th bit (implicitly stored)
int c_exp_val = a_exp_val + b_exp_val + 1;
if ((c_exp_val >= 0xff) || (c_exp_val <= 0))
{
// ble - NaN?
}
int c_exp_bits = ((c_exp_val + 127) & 0xFF) << 23;
int c_sign_bit = (a_bits & (1<<31)) ^ ((b_bits & (1<<31)));
int ret = c_sign_bit | c_exp_bits | (int)c;
return *((float*)&ret);
}
不完美,但似乎可以胜任。