c中如何加两次?

问题描述 投票:0回答:3

我正在尝试添加两次,例如 20:30 + 1:40 = 22h 10m。 我对点后的余数有疑问

#include <stdio.h>

float walking (float start,float duration);

int main() {
  printf ("finish = %.2f", walking(20.30, 1.40));
  return 0;
}

float walking(float start, float duration) {
  int finMinuites = (int)(start * 100) % 100 + (int)(duration * 100) % 100;
  int finHours = (start * 100) / 100 + (duration * 100) / 100;

  if (finMinuites >= 60) {
    finMinuites -= 60;
    finHours++;
  }

  if (finHours >= 24)
    finHours -= 24;

    return finHours + finMinuites / 100;
  }
c time
3个回答
1
投票

如果您确实想将时间存储在浮点数中,那么这里有一个解决方案:

#include<stdio.h>
#include<math.h>

float walking(float start,float duration);
int main() {
    printf("finish = %.2f",walking(20.30, 1.40));
    return 0;
}
int toMinutes(float time){
    int t = (int)round((time*100));
    int hours = t/100;
    int min = t - hours * 100;
    return hours*60+min;
}
float toFloat(int minutes){
    int hours = minutes/60;
    int min = minutes - hours * 60;
    float t = hours * 100;
    t += min;
    t /= 100;
    return t;
}
float walking(float start,float duration){
    int mins = toMinutes(start) + toMinutes(duration);
    int day = 24*60;
    while(mins > day){
        mins -= day;
    }

    return toFloat(mins);
}

但我建议将分钟存储为 int。


1
投票

困难的部分是正确地破坏浮点变量(FP)。

float/double
无法表示许多值,例如 0.01 完全 等等 当
(int)(start * 100)
截断时,分钟 * 100 是略小于整数的分数时,
(int)
会失败。

而是将 FP 值分解为整数部分和分数部分 (

modf()
) 以获得小时和分钟,然后形成总的单个单位时间值。添加。然后将总和转换回小时.分钟。

使用

double
比使用
float
更有意义,因为 OP 正在使用
double
测试用例常量。此外
float
应保留用于需要/从中受益的强制性条件,而不是默认的
double

无需扩展到分钟。使代码更简单。 简单易行.

#include <math.h>

double to_hours(double hours_dot_minutes) {
  double h;
  double m = modf(hours_dot_minutes, &h) * 100.0;
  return h + m/60.0;
}

double reduce_to_a_day(double hours) {
  const double hours_per_day = 24.0;
  hours = fmod(hours, hours_per_day);
  if (hours < 0.0) {
    hours += hours_per_day;
  }
  return hours;
}

double to_hours_dot_minutes(double hours) {
  double h;
  double m = modf(hours, &h) * 60.0;
  return h + m/100.0;
}

double walking(double start, double duration) {
  double sum = to_hours(start) + to_hours(duration);
  sum = reduce_to_a_day(sum);
  return to_hours_dot_minutes(sum);
}

请注意,

int
数学没有在任何地方使用。 IMO,浮点问题最好用 FP 数学处理,整数问题用整数数学处理,文本问题用文本操作处理。混合方法经常会在边缘情况下遇到问题 - 例如 OP 使用
(int)
来解决 FP 问题。


如果仍想在有限的值范围内使用强制转换,

double walking(double start, double duration) {
  int start_h = (int) start;
  int duration_h = (int) duration;
         
  double sum = start_h + duration_h + 
      ((start - start_h) + (duration - duration_h)) * 100.0 / 60.0;
  while  (sum >= 24.0) sum -= 24.0;
  int sum_h = (int) sum;
  return sum_h + (sum - sum_h) * 60.0 / 100.0;
}

1
投票

按照@ryyker的建议,您可以使用字符串让生活变得简单,而无需更改调用参数:

#include <stdio.h>
#include <stdlib.h>

double walking( double bgn, double dur ) {
    printf( "Start = %5.2f  duration = %5.2f  ", bgn, dur );
    char str[32];

    sprintf( str, "%.2f %.2f", bgn, dur );
    int res = 0, cnt = 1;
    for( char *cp = str; ( cp = strtok( cp, " ." ) ) != NULL; cp = NULL )
        res += atoi( cp ) * (cnt&1 ? 60 : 1), cnt++;

    return res/60%24 + ((res%60)*0.01);
}

int main( void ) {
    double pairs[][2] = {
        { 20.30,  1.40 },
        {  1.47,  1.13 },
        {  0.00,  1.13 },
        {  0.00,  0.00 },
        { 23.59,  0.01 },
        { 12.00, 48.27 },
    };

    for( int i = 0; i < sizeof pairs/sizeof pairs[0]; i++ )
        printf ( "finish = %5.2f\n", walking( pairs[i][0], pairs[i][1] ) );

    return 0;
}

输出

Start = 20.30  duration =  1.40  finish = 22.10
Start =  1.47  duration =  1.13  finish =  3.00
Start =  0.00  duration =  1.13  finish =  1.13
Start =  0.00  duration =  0.00  finish =  0.00
Start = 23.59  duration =  0.01  finish =  0.00
Start = 12.00  duration = 48.27  finish = 12.27

有人指出,这种方法可能不适用于

Dr Who
和其他能够穿越到过去的时间旅行者。对于那些不适用热力学第二定律的人,以下显示了必要的更改:

sprintf( str, "%.2f %.2f", bgn, dur );
int res = 0, cnt = 1, sgn = 1;
for( char *cp = str; ( cp = strtok( cp, " ." ) ) != NULL; cp = NULL, cnt++ )
    res += atoi( cp )
        * (cnt&1 ? 60 : 1)
        * sgn,
    sgn = *cp == '-' ? -1 : 1;

/* then one additional test case */

    { 12.00, -2.30 },

/* Output of the single test case: */

Start = 12.00  duration = -2.30  finish =  9.30

由于OP中显示的第一个参数似乎使用24小时时钟,因此没有尝试从“零下十一点三十分”开始进行测试。

享受你的散步。离开时请把垃圾带走...

© www.soinside.com 2019 - 2024. All rights reserved.