左移和右移以防止分割损失

时间:2017-07-17 21:37:21

标签: c integer division pic 16-bit

我不允许在我的C代码中使用浮点变量(出于性能原因)。我想执行整数除法运算,同时我想尽可能地防止除法损失。

我的理解是,如果分子是一个大数,则除法运算将产生良好的结果。目前我正在对分子进行左移操作以使其成为一个大数,然后我将分子除以分母。在最后的结果中,我正在做右移以补偿我原来的左移操作。我的问题是,这会改善分工结果吗?

例如要实现x = y / z,我正在编写我的“C”代码,如下所示,

x = y << 4;
x = x / z;
x = x >> 4;

1 个答案:

答案 0 :(得分:0)

你的意思是分裂损失究竟是什么意思?

如果您想要一个舍入除法,例如div(19,10) -> 2,并且您知道xy是正数,则可以执行以下操作:

(x + y / 2) / y

2除以y之外,y除以0非常有效,除非INT_MIN是编译时常数,在这种情况下,除法将被编译成乘法加调整。

您还必须避免分组溢出,例如-1除以out = out * ratio_n / ratio_d; 除以*

如果您想计算缩放比例,则必须在分割之前执行乘法

/

a * b / c(a * b) / c具有相同的优先级并且是左关联的,这意味着out = (long long)out * ratio_n / ratio_d; 被解析为out = ((long long)out * ratio_n + ratio_d / 2) / ratio_d;

您可能需要使用更大的类型作为中间结果:

int

你可以结合两种技术:

long

如果你的系统有16位out = ((long)out * ratio_n + ratio_d / 2) / ratio_d; ,你应该只使用int作为中间类型,因为它保证至少有32位:

  - ORDERER_GENERAL_LOGLEVEL=debug
  - ORDERER_GENERAL_LISTENADDRESS=0.0.0.0
  - ORDERER_GENERAL_GENESISMETHOD=file
  - ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block
  - ORDERER_GENERAL_LOCALMSPID=OrdererMSP
  - ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp
  # enabled TLS
  - ORDERER_GENERAL_TLS_ENABLED=true
  - ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key
  - ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt
  - ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]

但请注意,如果结果超出类型public class Application : Gtk.Window { public Application () { // Prepare Gtk.Window: this.window_position = Gtk.WindowPosition.CENTER; this.destroy.connect (Gtk.main_quit); // VBox: Gtk.Box vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5); this.add (vbox); // HeaderBar: Gtk.HeaderBar hbar = new Gtk.HeaderBar (); hbar.set_title ("MyFileChooser"); hbar.set_subtitle ("Select Files and Folders"); // HeaderBar Buttons Gtk.Button cancel = new Gtk.Button.with_label ("Cancel"); Gtk.Button select = new Gtk.Button.with_label ("Select"); hbar.pack_start (cancel); hbar.pack_end (select); this.set_titlebar (hbar); // Add a chooser: Gtk.FileChooserWidget chooser = new Gtk.FileChooserWidget (Gtk.FileChooserAction.OPEN); vbox.pack_start (chooser, true, true, 0); // Multiple files can be selected: chooser.select_multiple = true; // Add a preview widget: Gtk.Image preview_area = new Gtk.Image (); chooser.set_preview_widget (preview_area); chooser.update_preview.connect (() => { string uri = chooser.get_preview_uri (); // We only display local files: if (uri.has_prefix ("file://") == true) { try { Gdk.Pixbuf pixbuf = new Gdk.Pixbuf.from_file (uri.substring (7)); Gdk.Pixbuf scaled = pixbuf.scale_simple (150, 150, Gdk.InterpType.BILINEAR); preview_area.set_from_pixbuf (scaled); preview_area.show (); } catch (Error e) { preview_area.hide (); } } else { preview_area.hide (); } }); // HBox: Gtk.Box hbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5); vbox.pack_start(hbox, false, false, 0); // Setup buttons callbacks cancel.clicked.connect (() => { this.destroy (); }); select.clicked.connect (() => { SList<string> uris = chooser.get_uris (); foreach (unowned string uri in uris) { stdout.printf (" %s\n", uri); } this.destroy (); }); } public static int main (string[] args) { Gtk.init (ref args); Application app = new Application (); app.show_all (); Gtk.main (); return 0; } } 的范围,则行为是实现定义的。