堕落帝国觉醒代码:与帝国单位合作(what is imperial measurement)

关于堕落帝国觉醒代码的问题,在what is imperial measurement中经常遇到, 我正在玩弄一个应用程序,粗略地说,这是建筑行业的另一种建模器应用程序。将来,我希望用户可以同时使用 SI 单位和英制。根据我的理解,在美国建筑行业中,通常在指定测量值时会使用英寸的分数,例如输入 3 1 / 2“-而在 SI 中,我们将编写 3.5,而不是 3 1 / 2。我正在寻找一种方法来使用这些不同的系统进行分析。

我正在玩弄一个应用程序,粗略地说,这是建筑行业的另一种建模器应用程序。将来,我希望用户可以同时使用 SI 单位和英制。根据我的理解,在美国建筑行业中,通常在指定测量值时会使用英寸的分数,例如输入 3 1 / 2“-而在 SI 中,我们将编写 3.5,而不是 3 1 / 2。我正在寻找一种方法来使用这些不同的系统进行分析。

我还不确定我应该为用户输入数据增加多少灵活性;例如,如果他输入 1 英尺 14 英寸,下次显示测量时应该是 2 英尺 2 英寸吗?但是在我决定这样的事情之前,我正在寻找一种以精确形式存储测量值的方法,这就是我的问题。

我使用 C ++,我已经看过 Boost.Units,但这似乎并没有提供一种处理分数的方法。

简单的选择是将所有内容转换为毫米,但是舍入误差将使得不可能回到用户输入的精确测量(如果他在英制测量中输入)。

现在我使用一个暂时命名为“距离”的类,在概念上看起来像这样:

class Distance
{
public:
    Distance(double value);
    // operators +, -, *, /
    Distance operator+(const Distance& that);
    ...etc...
    std::string StringForm(); // Returns a textual form of the value
    Distance operator=(double value);
private:
    <question: what should go here?>
}

这清楚地显示了我的问题在哪里。要做的最明显的事情是有一个枚举,它说这个距离是存储 SI 还是英制单位,并且如果它是以 SI 单位存储米,厘米和毫米的字段(大概是双打),如果它是英制的,则是英尺和英寸。但是,这将使类的实现充满 if(SI)else...,并且在内存中非常浪费 1 英寸来存储分子和

因此,鉴于我的设计要求,我正在寻找有关如何解决这些问题的一般设计建议。当然,如果有一个 C ++ 库已经做了这些事情,或者是另一种语言的库,我可以看看从复制概念,那就太好了。

5

看看 Martin Fowler 的Money模式来自Patterns of Enterprise Application Architecture— — 它直接适用于这种情况。推荐阅读。Fowler 还在他的网站上发布了一篇关于Quantity模式的简短文章,这是一个更通用的 Money 版本。

5

我肯定会考虑在 distance 类中添加一个 Units 属性。然后,您可以重载 +,-,*,/(和相关)运算符,以便只有当单位是相同类型时,才可能对距离进行算术运算。

就我个人而言,我会将所有测量值标准化为您将在每个系统中支持的最低测量单位(例如,SI 为毫米,英制为英寸),但也存储用户输入的表示形式。以规范化的形式执行所有计算,但在呈现给用户时转换回更可读的形式。

您还应该考虑使 Distance 的实例不可变-并在执行算术运算时创建新的 Distance。

最后,您可以创建辅助方法以在不同单位之间进行转换-甚至可能在使用不同单位对距离进行算术运算时在内部调用这些方法。

就个人而言,我不会去创建多种类型的测量在每个系统的路线-我认为你是更好地巩固逻辑,并允许您的系统多态处理测量。

1

你是对的,将所有转换为一种测量类型会给用户带来烦人的舍入错误。

你应该做一个声明操作的虚拟基类。

您应该为要实现的每个测量系统提供一个具体的子类:例如公制,美国帝国,古罗马。在内部,这可以以最合适和准确的格式存储它们-例如,英制的几分之一英寸。

您将需要每个子类(测量系统)的字符串输出机制。

您应该有一个工厂将字符串表示转换为适当类的实例。

您将需要为每个子类实现操作(如 add),保留类型,因此帝国 + 帝国使帝国。

您将需要实现交叉类型操作,并决定如果添加毫米和英寸,您希望发生什么。它应该输出公制还是英制类?

-亚历克斯

1

美国测量(有些人称之为“英语”或“帝国”单位;我们喜欢责怪别人为我们的错误)要求你有理性的数字包来存储英寸。

对于公制,您有几个具有简单关系的不同单位 (cm 、 m 、 km 等)。将它们视为具有简单转换因子的独立单位。m 到 cm 是 * 100 转换。您可以轻松地枚举所有可能的公制距离度量中的所有 * 100 、 * 1000 、 *.1 、 *.01 转换因子。

对于英语,单位(英寸,英尺,码等)也有简单的关系。他们只是不迷恋十进制。使用 12 和 3 而不是 10。将它们视为具有简单转换因子的单独单位。ft 到 in 是 * 12 转换。同样,您可以轻松枚举所有 * 12,* 36,*(1 / 12),*(1 / 36)组合。

当有人输入 3 '8 "时,您可以将其归一化为英寸并正确转换回来。即使他们输入 3' 14",您转换回 4 '2 "是正确的,也是预期的。在某些情况下,这是期望的。

在某些情况下-即使是英文表示法-也有一个所需的输出单位,而不是原始输入单位。例如,某人可能有一长串以英尺和英寸为单位的测量值,但想要以十进制为单位的总和。批量购买时,您不在乎它是 25 '6 7 / 16“;25.54' 是一个很好的答案。您要购买 26 '的木材,这通常意味着 3 10' 板。

事实证明,这个单位转换适用于 m 到 ft 和 back。您可以枚举 in,ft,yd,mm,cm,m,km 转换的每种组合。输入单位被归一化为短(cm,in),并在输出时转换为所需单位(m,ft,yd 等)

您可以存储 1356 英寸。这很好。您可以显示 113 '或 37.66 yds,或 37 yds 2 ft。取决于用户选择的输出单位。

这个方案适用于除温度以外的任何东西。

唯一的障碍是几分之一英寸。这样做需要一个 Rational number 包。您想要的是像这样的类层次结构。

Distance
|
+---- Float (no fractions, everything but inches)
|
+---- Rational (fractions used for inches)

如果它提供了适当的函数来在 int 和 float 之间进行转换,你应该能够将两者混合并得到合理的答案,而无需太多 RTTI。

这是奇怪的。英寸使用 2 的幂,并有精确的浮点表示。没有 24.000000001 或其他转换的工件。公制使用 10 的幂,所以你得到各种愚蠢的 24.00000001 和 23.99999997 答案公制计算。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(371)
Ch开头的手表:将以Aa开头的单词匹配到Ch的正则表达式
上一篇
Csi感受静态之美:Kubernetes CSI驱动升级
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(1条)